php連接不上mysql的原因有很多種常用的可能是函數沒開啟或mysql數據庫配置有問題,下面我來給大家介紹php連接不上MySQL一些問題的分析與解決方法。
現象1
在PHP error log裡發現:
PHP Warning: mysqli::mysqli(): (HY000/2003): Can’t connect to MySQL server on ‘XXX.XXX.XXX.XXX’ (99) in /u1/www/XXXX.php on line 10
PHP Warning: mysqli::close(): Couldn’t fetch mysqli in /u1/www/XXXX.php on line 11
推斷:只有在高並發的環境下出現
診斷分析:
通過MySQL數據庫上抓包,沒發現異常。又把目標轉到php 服務器上。
BTW:
linux開著selinux連接MySQL在測試中基本上屬於1ms+,禁掉selinux後在0.96左右。selinux還是要禁掉的。
既然又懷疑是PHP的問題就寫一個程序測試(禁掉selinux後):
cat tconn.php
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$time_start = microtime_float();
for ( $i=0; $i<30000; $i++){
$dbh=new mysqli("XXX.XXX.XXX.XXX", "wubx", "wubxwubx", "userdb", 3308);
$dbh->close();
}
$time_end= microtime_float();
$time_use= ($time_end - $time_start)/30000;
print "$time_usen";
#php tconn.php
0.00090954260031382
再次運行就開始大量的報錯。
PHP Warning: mysqli::mysqli(): (HY000/2003): Can't connect to MySQL server on 'XXX.XXX.XXX.XXX' (99) in /u1/www/XXXX.php on line 10
PHP Warning: mysqli::close(): Couldn't fetch mysqli in /u1/www/XXXX.php on line 11
中止該程序後,通過
#strace php tconn.php 運行
得到:
connect(3, {sa_family=AF_INET, sin_port=htons(3308), sin_addr=inet_addr("XXX.XXX.XXX.XXX")}, 16) = -1 EADDRNOTAVAIL (Cannot assign requested address)
shutdown(3, 2 /* send and receive */) = -1 ENOTCONN (Transport endpoint is not connected)
看到這個大概明白是本地的網絡可能注冊不上了,也難怪在MySQL抓包看也正常。
看樣子是本地tcp不能重用造成的。改一下在測試
代碼如下 復制代碼 sysctl -w net.ipv4.tcp_tw_reuse=1;在次測試問題不存在了。在這個上面碰了一下後順便改一下/etc/sysctl.conf添加:
代碼如下 復制代碼net.ipv4.tcp_max_syn_backlog = 819200
net.core.netdev_max_backlog = 400000
net.core.somaxconn = 4096
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=0
#sysctl -p
問題解決
現象2
MYSQL.測試連接mysql 提示'Fatal error: Call to undefined function mysql_connect()"環境j是:windows xp sp2 en , apache2.2,mysql5.1rc.php5.28。
這個提示,會不會是php沒有加載到連接mysql的庫文件呢? 在啟動apache server後.我試著刪除'php5ts.dll'和'libmysql.dll'.提示不能刪除.說明有程序在用著這兩個庫文件.說明是有加載的.(當然有許多方法來測試.比如可以用一些軟件,查看程序服務加載的所有庫文件.也是可以然而ap也說指是php.ini設置有問題.那我就不看別的.我就重點針對php.ini配置.
在沒有迷信php.ini是正確下.終於發現.php.ini中漏了這一行.
PHPIniDir "你的php目錄"
#(例如: PHPIniDir "c:/php")
重啟apache server,然後.用網上常用的方法
以下為引用的內容:
測試一下.就可以了
總結一下這些問題
1. 首先要排查網絡問題和防火牆的問題
這個是必須的, 你要是連MySQL的服務器都連不上, 那還訪問什麼? 怎麼檢查呢? ping一下 ping 192.168.0.11 ping 的通的話, 再去檢查一下 3306端口是不是被防火牆給擋掉了 ping 192.168.0.11:3306 或者干脆把防火牆關掉,service iptables stop (Redhat ) 或 ufw disable(ubuntu) 這一步沒問題的話, 開始下一步:
2. 要排查有沒有訪問權限
說到訪問權限, MySQL分配用戶的時候會指定一個host, 比如我的 host 指定為 192.168.0.5 , 那麼這個賬號就只能 .5 這一台機器訪問, 其他的機器用這個賬號訪問會提示沒有權限。 host 指定為 % 則表示允許所有的機器訪問。 一般來說出於安全方面的考慮,遵循最小權限原則, 權限的問題就不多講了, 不會的自己查手冊。 確定了權限沒問題的話進行下一步:
3. 要排查MySQL的配置
檢查mysql的配置文件, Linux下MySQL的配置文件叫 my.cnf windows下的叫 my.ini,檢查這個配置項: –bind-address=IP
引用手冊裡的一段話:
The IP address to bind to. Only one address can be selected. If this option is specified multiple times, the last address given is used. If no address or 0.0.0.0 is specified, the server listens on all interfaces.
綁定的IP, 只能綁定一個IP, 如果綁定多個IP, 則以最後一個綁定的為准。 如果沒有綁定或綁定 0.0.0.0, 服務器監聽所有的客戶端。
我曾經就被這個東西害慘過, 有一次搞了一個下午沒搞定, 檢查網絡通的, 檢查權限沒問題, 客戶端就是死活連不上, 一看手冊明白了。 所以有什麼問題還是要多看手冊