最近遇到一個問題,就是在高并發下,mysql性能出現了瓶頸,由于PHP是一種弱類型的語言,沒有類型一說。是以,當mysql傳回并非預期結果時,會導緻後續邏輯錯誤。
1)線程阻塞測試
當sql語句執行太慢,會導緻mysql的連接配接數被耗盡,無法處理新的請求。
測試方法
執行set global max_connections=1;語句,并在另一個程式中開啟長連接配接占用該連接配接,此時,mysql服務已經無連接配接可用。
PHP代碼如下:
<?php
$con=mysql_connect('127.0.0.1','root','');
var_dump($con);
sleep(10);
mysql_select_db('test',$con);
$cursor=mysql_query("select * from `timeout_test` where `id`=2 for update");
var_dump($cursor);
var_dump(mysql_fetch_assoc($cursor));
echo "done!";
傳回結果,mysql_connect 和mysql_query都傳回false錯誤
2)鎖阻塞測試
恢複正常的連結數,執行set autocomit=0; 我使用的是innodb引擎,myisam引擎沒有事務概念,autocomit的值在myisam下總為1。
在mysql連結中,執行語句:
mysql> select * from `timeout_test` where `id`=2 for update;
+----+------+
| id | name |
+----+------+
| 2 | kk |
+----+------+
1 row in set (0.00 sec)
接下來,執行上述PHP,傳回結果如下:
resource(5) of type (mysql link)
bool(false)
Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean given in D:\test\mysql-index\timeout.php on line 7
Call Stack:
0.0002 234472 1. {main}() D:\test\mysql-index\timeout.php:0
51.1252 242496 2. mysql_fetch_assoc() D:\test\mysql-index\timeout.php:7
NULL
done!PHP Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean given in D:\test\mysql-index\timeout.php on line 7
PHP Stack trace:
PHP 1. {main}() D:\test\mysql-index\timeout.php:0
PHP 2. mysql_fetch_assoc() D:\test\mysql-index\timeout.php:7
mysql_query傳回了false,此時如果強制使用mysql_fetch_assoc等擷取結果的函數,将會傳回NULL
3)總結
函數名稱 | 線程阻塞 | 鎖阻塞 |
mysql_connect | 函數值傳回false,并抛出一個warning級别錯誤,并不會終止程式。 | 傳回resource(3, mysql link), 正常 |
mysql_query | 函數值傳回false,并抛出一個warning級别錯誤,并不會終止程式。如果mysql_connect傳回false,即使連接配接被釋放,mysql_query不會重新連接配接到mysql | 傳回false,但不抛出異常。 對正常的mysql_query, 執行失敗傳回false。 程式中應當判斷這種錯誤。 |