PHP訪問MySQL查詢逾時處理的方法

來源:互聯網
上載者:User

目前兩個用戶端擴充功能庫連線逾時可以設定選項來操作,比如mysqli: 複製代碼 代碼如下:<?php
//建立對象
$mysqli = mysqli_init();
//設定逾時選項
$mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5);
//串連
$mysqli->real_connect('localhost', 'my_user', 'my_password', 'world');
//如果逾時或者其他串連失敗列印錯誤資訊
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
//成功輸出串連資訊
printf ("Connection: %s\n.", $mysqli->host_info);
$mysqli->close();
?>

這個是連線逾時,但是有些時候我們需要查詢讀寫逾時,比如說我們一個資料庫壓力很大,或者串連很多,那麼資料庫查詢就很緩慢,但是我希望某些不重要的資料,比如說文章點擊數這種如果查詢逾時了就不顯示,至少能夠保證主體頁面正確顯示,但是查遍PHP手冊沒有發現這個操作選項或者函數。

手冊裡只有這麼四個選項

跟蹤 mysqli 的擴充原始碼發現它底層調用的是 libmysqlclient 的 mysql_options:

php-5.2.8/ext/mysqli/mysqli_api.c

並且在mysqli的PHP擴充中就只匯出了幾個變數:

php-5.2.8/ext/mysqli/mysqli.c

大概看了一下 libmysqlclient 的代碼,發現其實它內建是有讀寫逾時設定的:

mysql-5.1.30/sql-common/client.c

因為它自己定義了很多操作選項,只是php擴充裡沒有:

mysql-5.1.30/include/mysql.h

看看mysql中的讀寫逾時是如何?的:

mysql-5.1.30/sql-common/client.c

讀寫逾時真正操作的地方,逾時處理這裡重試了兩次,還是寫死了:

mysql-5.1.30/sql/net_serv.cc

現在基本得出了結論:

按照上面查看代碼來看,目前PHP針對MySQL查詢逾時以下限制:

1. 逾時設定單位為秒,最少配置1秒

2. 但mysql底層的read會重試兩次,所以實際會是 3 秒

重試兩次 + 自身一次 = 3倍逾時時間。

那麼就是說最少逾時時間是3秒,不會低於這個值,對於大部分應用來說可以接受,但是對於小部分應用需要最佳化。
現在我們來看看如果我們自己要設定逾時,我們自己壓入 MYSQL_OPT_READ_TIMEOUT 也是可以達到讀寫逾時效果的,寫一段代碼來測試一下: 複製代碼 代碼如下:<?php
//自己定義讀寫逾時常量
if (!defined('MYSQL_OPT_READ_TIMEOUT')) {
define('MYSQL_OPT_READ_TIMEOUT', 11);
}
if (!defined('MYSQL_OPT_WRITE_TIMEOUT')) {
define('MYSQL_OPT_WRITE_TIMEOUT', 12);
}

//設定逾時
$mysqli = mysqli_init();
$mysqli->options(MYSQL_OPT_READ_TIMEOUT, 3);
$mysqli->options(MYSQL_OPT_WRITE_TIMEOUT, 1);

//串連資料庫
$mysqli->real_connect("localhost", "root", "root", "test");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}

//執行查詢 sleep 1秒不逾時
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";
}

//執行查詢 sleep 9秒會逾時
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";
?>

查看上面代碼的執行結果,驗證了上面的觀點,第一個查詢成功了,第二個查詢串連被斷開了:

如果需要修改這個秒層級的逾時,比如改成毫秒層級的逾時,只能兩個地方修改:

1. 修改用戶端,比如 mysqli 的 query 代碼,加入定時器,逾時則返回

2. 修改 Mysql 中的vio代碼,因為mysql的網路處理底層都是經過vio的操作

MySQL相關的vio代碼:

poll 逾時:

setsockopt 逾時:

基本上到這裡就基本能夠解決PHP在針對MySQL讀寫查詢操作逾時的處理了,希望對你有協助。
heiyeluren的blog

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.