PHP訪問MySQL查詢超時(shí)處理的方法
<?php
//創(chuàng)建對(duì)象
$mysqli = mysqli_init();
//設(shè)置超時(shí)選項(xiàng)
$mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5);
//連接
$mysqli->real_connect('localhost', 'my_user', 'my_password', 'world');
//如果超時(shí)或者其他連接失敗打印錯(cuò)誤信息
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
//成功輸出連接信息
printf ("Connection: %s\n.", $mysqli->host_info);
$mysqli->close();
?>
這個(gè)是連接超時(shí),但是有些時(shí)候我們需要查詢讀寫超時(shí),比如說我們一個(gè)數(shù)據(jù)庫壓力很大,或者連接很多,那么數(shù)據(jù)庫查詢就很緩慢,但是我希望某些不重要的數(shù)據(jù),比如說文章點(diǎn)擊數(shù)這種如果查詢超時(shí)了就不顯示,至少能夠保證主體頁面正確顯示,但是查遍PHP手冊(cè)沒有發(fā)現(xiàn)這個(gè)操作選項(xiàng)或者函數(shù)。
手冊(cè)里只有這么四個(gè)選項(xiàng)

跟蹤 mysqli 的擴(kuò)展源代碼發(fā)現(xiàn)它底層調(diào)用的是 libmysqlclient 的 mysql_options:
php-5.2.8/ext/mysqli/mysqli_api.c

并且在mysqli的PHP擴(kuò)展中就只導(dǎo)出了幾個(gè)變量:
php-5.2.8/ext/mysqli/mysqli.c

大概看了一下 libmysqlclient 的代碼,發(fā)現(xiàn)其實(shí)它自帶是有讀寫超時(shí)設(shè)置的:
mysql-5.1.30/sql-common/client.c

因?yàn)樗约憾x了很多操作選項(xiàng),只是php擴(kuò)展里沒有:
mysql-5.1.30/include/mysql.h

看看mysql中的讀寫超時(shí)是如何實(shí)現(xiàn)的:
mysql-5.1.30/sql-common/client.c


讀寫超時(shí)真正操作的地方,超時(shí)處理這里重試了兩次,還是寫死了:
mysql-5.1.30/sql/net_serv.cc


現(xiàn)在基本得出了結(jié)論:
按照上面查看代碼來看,目前PHP針對(duì)MySQL查詢超時(shí)以下限制: 1. 超時(shí)設(shè)置單位為秒,最少配置1秒 2. 但mysql底層的read會(huì)重試兩次,所以實(shí)際會(huì)是 3 秒 重試兩次 + 自身一次 = 3倍超時(shí)時(shí)間。 那么就是說最少超時(shí)時(shí)間是3秒,不會(huì)低于這個(gè)值,對(duì)于大部分應(yīng)用來說可以接受,但是對(duì)于小部分應(yīng)用需要優(yōu)化。 查看上面代碼的執(zhí)行結(jié)果,驗(yàn)證了上面的觀點(diǎn),第一個(gè)查詢成功了,第二個(gè)查詢連接被斷開了:
如果需要修改這個(gè)秒級(jí)別的超時(shí),比如改成毫秒級(jí)別的超時(shí),只能兩個(gè)地方修改: 1. 修改客戶端,比如 mysqli 的 query 代碼,加入定時(shí)器,超時(shí)則返回 2. 修改 Mysql 中的vio代碼,因?yàn)?/SPAN>mysql的網(wǎng)絡(luò)處理底層都是經(jīng)過vio的操作
MySQL相關(guān)的vio代碼:
poll 超時(shí):
setsockopt 超時(shí):
基本上到這里就基本能夠解決PHP在針對(duì)MySQL讀寫查詢操作超時(shí)的處理了,希望對(duì)你有幫助。
現(xiàn)在我們來看看如果我們自己要設(shè)置超時(shí),我們自己壓入 MYSQL_OPT_READ_TIMEOUT 也是可以達(dá)到讀寫超時(shí)效果的,寫一段代碼來測(cè)試一下:
<?php
//自己定義讀寫超時(shí)常量
if (!defined('MYSQL_OPT_READ_TIMEOUT')) {
define('MYSQL_OPT_READ_TIMEOUT', 11);
}
if (!defined('MYSQL_OPT_WRITE_TIMEOUT')) {
define('MYSQL_OPT_WRITE_TIMEOUT', 12);
}
//設(shè)置超時(shí)
$mysqli = mysqli_init();
$mysqli->options(MYSQL_OPT_READ_TIMEOUT, 3);
$mysqli->options(MYSQL_OPT_WRITE_TIMEOUT, 1);
//連接數(shù)據(jù)庫
$mysqli->real_connect("localhost", "root", "root", "test");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
//執(zhí)行查詢 sleep 1秒不超時(shí)
printf("Host information: %s\n", $mysqli->host_info);
if (!($res=$mysqli->query('select sleep(1)'))) {
echo "query1 error: ". $mysqli->error ."\n";
} else {
echo "Query1: query success\n";
}
//執(zhí)行查詢 sleep 9秒會(huì)超時(shí)
if (!($res=$mysqli->query('select sleep(9)'))) {
echo "query2 error: ". $mysqli->error ."\n";
} else {
echo "Query2: query success\n";
}
$mysqli->close();
echo "close mysql connection\n";
?> 


heiyeluren的blog
相關(guān)文章
MySQL數(shù)據(jù)中很多換行符和回車符的解決方法
這篇文章主要給大家介紹了關(guān)于MySQL數(shù)據(jù)中很多換行符和回車符的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
MySQL實(shí)現(xiàn)定時(shí)自動(dòng)備份的流程步驟(Windows環(huán)境)
這篇文章主要介紹了MySQL實(shí)現(xiàn)定時(shí)自動(dòng)備份的流程步驟(Windows環(huán)境),文中通過圖文結(jié)合的方式介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-12-12
mysql drop database刪除數(shù)據(jù)庫命令實(shí)例講解
這篇文章主要介紹了mysql drop database刪除數(shù)據(jù)庫命令實(shí)例講解的相關(guān)資料,需要的朋友可以參考下2016-09-09
MySQL深入詳解delete與Truncate及drop的使用區(qū)別
對(duì)于drop、truncate和delete雖然簡單,但是真要使用或者面試時(shí)候問到還是需要有一定的總結(jié),下面這篇文章主要給大家介紹了關(guān)于mysql中drop、truncate與delete區(qū)別的相關(guān)資料,需要的朋友可以參考下2022-07-07
sql如何使用group by分組,同時(shí)查詢其它字段
文章介紹了使用SQL的GROUP BY進(jìn)行分組查詢時(shí)的一些規(guī)則和技巧,主要強(qiáng)調(diào)了在SELECT后面的字段要么是聚合函數(shù)的一部分,要么必須包含在GROUP BY子句中,此外,文章還討論了如何在GROUP BY時(shí)查詢其他字段,通過使用MAX或MIN函數(shù)來實(shí)現(xiàn)2024-12-12
解決MySQL因不能創(chuàng)建臨時(shí)文件而導(dǎo)致無法啟動(dòng)的方法
這篇文章主要跟大家介紹了關(guān)于解決MySQL因不能創(chuàng)建臨時(shí)文件而導(dǎo)致無法啟動(dòng)的方法,文中通過示例代碼介紹了詳細(xì)的解決方法,對(duì)大家具有一定的的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-06-06
CenOS6.7下mysql 8.0.22 安裝配置方法圖文教程
這篇文章主要為大家詳細(xì)介紹了CenOS6.7下mysql 8.0.22 安裝配置方法圖文教程,文中安裝步驟介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11

