溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

mysql timeout變量的示例分析

發(fā)布時(shí)間:2020-12-23 09:56:52 來源:億速云 閱讀:165 作者:小新 欄目:MySQL數(shù)據(jù)庫

小編給大家分享一下mysql timeout變量的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

1、timeout變量知多少

打開mysql,用show variables like '%timeout%'命令一看,不看不知道,一看嚇一跳,結(jié)果如下面所示,這么多timeout相關(guān)變量,一下就嚇尿了。。原來對mysql的了解原來是如此的不夠,好了,這么些timeout究竟各自是什么意思,花了一下午去學(xué)習(xí),做了幾個(gè)小實(shí)驗(yàn),總算明白了一二,如有錯(cuò)誤,請不吝賜教啊。

mysql> show variables like '%timeout%';
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| connect_timeout             | 10       |
| delayed_insert_timeout      | 300      |
| innodb_flush_log_at_timeout | 1        |
| innodb_lock_wait_timeout    | 50       |
| innodb_rollback_on_timeout  | OFF      |
| interactive_timeout         | 28800    |
| lock_wait_timeout           | 31536000 |
| net_read_timeout            | 30       |
| net_write_timeout           | 60       |
| rpl_stop_slave_timeout      | 31536000 |
| slave_net_timeout           | 3600     |
| wait_timeout                | 28800    |
+-----------------------------+----------+

2.分析

下面從timeout里面找些比較常用的出來逐個(gè)分析下。

2.1 connect_timeout

connect_timeout指的是連接過程中握手的超時(shí)時(shí)間,在5.0.52以后默認(rèn)為10秒,之前版本默認(rèn)是5秒。官方文檔是這樣說的:

connect_timeout: The number of seconds that the mysqld server waits for a connect packet before responding with Bad handshake. The default value is 10 seconds as of MySQL 5.0.52 and 5 seconds before that

mysql的基本原理應(yīng)該是有個(gè)監(jiān)聽線程循環(huán)接收請求,當(dāng)有請求來時(shí),創(chuàng)建線程(或者從線程池中取)來處理這個(gè)請求。由于mysql連接采用TCP協(xié)議,那么之前勢必是需要進(jìn)行TCP三次握手的。TCP三次握手成功之后,客戶端會(huì)進(jìn)入阻塞,等待服務(wù)端的消息。服務(wù)端這個(gè)時(shí)候會(huì)創(chuàng)建一個(gè)線程(或者從線程池中取一個(gè)線程)來處理請求,主要驗(yàn)證部分包括host和用戶名密碼驗(yàn)證。host驗(yàn)證我們比較熟悉,因?yàn)樵谟胓rant命令授權(quán)用戶的時(shí)候是有指定host的。用戶名密碼認(rèn)證則是服務(wù)端先生成一個(gè)隨機(jī)數(shù)發(fā)送給客戶端,客戶端用該隨機(jī)數(shù)和密碼進(jìn)行多次sha1加密后發(fā)送給服務(wù)端驗(yàn)證。如果通過,整個(gè)連接握手過程完成。(具體握手過程后續(xù)找到資料再分析)

由此可見,整個(gè)連接握手可能會(huì)有各種可能出錯(cuò)。所以這個(gè)connect_timeout值就是指這個(gè)超時(shí)時(shí)間了??梢院唵螠y試下,運(yùn)行下面的telnet命令會(huì)發(fā)現(xiàn)客戶端會(huì)在10秒后超時(shí)返回。

telnet localhost 3306

在超時(shí)之前mysql中該連接狀態(tài)如下:

256 | unauthenticated user | localhost:60595 | NULL | Connect | NULL | Reading from net | NULL

2.2 interactive_timeout & wait_timeout

還是先看官方文檔,從文檔上來看wait_timeout和interactive_timeout都是指不活躍的連接超時(shí)時(shí)間,連接線程啟動(dòng)的時(shí)候wait_timeout會(huì)根據(jù)是交互模式還是非交互模式被設(shè)置為這兩個(gè)值中的一個(gè)。如果我們運(yùn)行mysql -uroot -p命令登陸到mysql,wait_timeout就會(huì)被設(shè)置為interactive_timeout的值。如果我們在wait_timeout時(shí)間內(nèi)沒有進(jìn)行任何操作,那么再次操作的時(shí)候就會(huì)提示超時(shí),這是mysql client會(huì)重新連接。

The number of seconds the server waits for activity on a noninteractive connection before closing it.

On thread startup, the session wait_timeout value is initialized from the global wait_timeout value or from the global interactive_timeout value, depending on the type of client (as defined by the CLIENT_INTERACTIVE connect option to mysql_real_connect()).

測試如下:

mysql> set global interactive_timeout=3; ##設(shè)置交互超時(shí)為3秒

重新進(jìn)入mysql,這時(shí)候可以看到:

mysql> show variables like '%timeout%'; ##wait_timeout已經(jīng)被設(shè)置為3秒
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| connect_timeout             | 10       |
| delayed_insert_timeout      | 300      |
| innodb_flush_log_at_timeout | 1        |
| innodb_lock_wait_timeout    | 50       |
| innodb_rollback_on_timeout  | OFF      |
| interactive_timeout         | 3        |
| lock_wait_timeout           | 31536000 |
| net_read_timeout            | 30       |
| net_write_timeout           | 3        |
| rpl_stop_slave_timeout      | 31536000 |
| slave_net_timeout           | 3600     |
| wait_timeout                | 3        |
+-----------------------------+----------+

可以看到wait_timeout被設(shè)置為了interactive_timeout的值,這樣,我們3秒后再執(zhí)行其他命令,會(huì)提示如下:

mysql> show variables like '%timeout%';
ERROR 2006 (HY000): MySQL server has gone away  ##超時(shí)重連
No connection. Trying to reconnect...
Connection id:    50
Current database: *** NONE ***

+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| connect_timeout             | 10       |
| delayed_insert_timeout      | 300      |
| innodb_flush_log_at_timeout | 1        |
| innodb_lock_wait_timeout    | 50       |
| innodb_rollback_on_timeout  | OFF      |
| interactive_timeout         | 3        |
| lock_wait_timeout           | 31536000 |
| net_read_timeout            | 30       |
| net_write_timeout           | 3        |
| rpl_stop_slave_timeout      | 31536000 |
| slave_net_timeout           | 3600     |
| wait_timeout                | 3        |
+-----------------------------+----------+

2.3 innodb_lock_wait_timeout & innodb_rollback_on_timeout

還是先祭出官方文檔,從文檔中看,這個(gè)值是針對innodb引擎的,是innodb中行鎖的等待超時(shí)時(shí)間,默認(rèn)為50秒。如果超時(shí),則當(dāng)前語句會(huì)回滾。如果設(shè)置了innodb_rollback_on_timeout,則會(huì)回滾整個(gè)事務(wù),否則,只回滾事務(wù)等待行鎖的這個(gè)語句。

The length of time in seconds an InnoDB transaction waits for a row lock before giving up. The default value is 50 seconds. A transaction that tries to access a row that is locked by another InnoDB transaction waits at most this many seconds for write access to the row before issuing the following error:

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

同樣來測試下(先創(chuàng)建一個(gè)innodb引擎的表test,只有一列,列名為a):

mysql> CREATE TABLE `test` ( `a` int primary key) engine=innodb;

首先插入三條測試數(shù)據(jù)

mysql> select * from test;
+---+
| a |
+---+
| 1 |
| 2 |
| 3 |

當(dāng)前innodb_rollback_on_timeout=OFF,設(shè)置innodb_lock_wait_timeout=1,我們開啟兩個(gè)事務(wù)

##事務(wù)1 加行鎖
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test where a=2 for update;
+---+
| a |
+---+
| 2 |
+---+
1 row in set (0.01 sec)
##事務(wù)2,請求行鎖
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> delete from test where a=1;
Query OK, 1 row affected (0.00 sec)

mysql> delete from test where a=2; ##請求行鎖超時(shí)
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> select * from test;
+---+
| a |
+---+
| 2 |
| 3 |
+---+
2 rows in set (0.00 sec)

mysql> begin; ##這里我們直接開啟另外的事務(wù)(或者直接commit當(dāng)前事務(wù)),則原來的事務(wù)只會(huì)回滾第二條語句,最終結(jié)果就是test表中只剩下2和3.如果這里我們顯示的rollback,則會(huì)回滾整個(gè)事務(wù),保持1,2,3不變。

那么如果innodb_rollback_on_timeout=ON,同樣事務(wù)2會(huì)超時(shí),但是這個(gè)時(shí)候如果我們begin開啟新的事務(wù),那么會(huì)回滾請求鎖超時(shí)的整個(gè)事務(wù),而不是像前面那樣只回滾了超時(shí)的那條語句。

2.4 lock_wait_timeout

文檔中描述如下,簡單說來lock_wait_timeout是元數(shù)據(jù)鎖等待超時(shí),任意鎖元數(shù)據(jù)的語句都會(huì)用到這個(gè)超時(shí)參數(shù),默認(rèn)為一年。元數(shù)據(jù)鎖可以參加mysql metadata lock,為了保證事務(wù)可串行化,不管是myisam還是innodb引擎的表,只要是先在一個(gè)session里面開啟一個(gè)事務(wù),就會(huì)獲取操作表的元數(shù)據(jù)鎖,這時(shí)候如果另一個(gè)session要對表的元數(shù)據(jù)進(jìn)行修改,則會(huì)阻塞直到超時(shí)。

This variable specifies the timeout in seconds for attempts to acquire metadata locks. The permissible values range from 1 to 31536000 (1 year). The default is 31536000.

This timeout applies to all statements that use metadata locks. These include DML and DDL operations on tables, views, stored procedures, and stored functions, as well as LOCK TABLES, FLUSH TABLES WITH READ LOCK, and HANDLER statements

測試?yán)樱?br/>我們用一個(gè)myisam引擎的表myisam_test來測試。其中有一條記錄(1,1),現(xiàn)在我們先開啟一個(gè)session,然后執(zhí)行一個(gè)select語句。另外打開一個(gè)session,然后執(zhí)行表的元數(shù)據(jù)操作,如刪除表,會(huì)發(fā)現(xiàn)操作阻塞直到lock_wait_timeout秒后提示超時(shí)。

##第一個(gè)session,獲取metadata lock
mysql> show create table myisam_test;
-----------------------------------------------------------+
| Table       | Create Table                                                                                                                                |
+-----------------------------------------------------------
| myisam_test | CREATE TABLE `myisam_test` (
  `i` int(11) NOT NULL,
  `j` int(11) DEFAULT NULL,
  PRIMARY KEY (`i`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from myisam_test;
+---+------+
| i | j    |
+---+------+
| 2 |    1 |
+---+------+
1 row in set (0.00 sec)

##另一個(gè)session,刪除表提示超時(shí)
mysql> drop table myisam_test;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

其中更改表結(jié)構(gòu)的元數(shù)據(jù)操作指令有如下這些:

DROP TABLE t;
ALTER TABLE t ...;
DROP TABLE nt;
ALTER TABLE nt ...;
LOCK TABLE t ... WRITE;

當(dāng)然,多說一句,對于myisam表的加鎖以及并發(fā)插入等,這篇博客myisam表鎖非常詳細(xì),有興趣的可以看看。

2.5 net_read_timeout & net_write_timeout

文檔中描述如下,就是說這兩個(gè)參數(shù)在網(wǎng)絡(luò)條件不好的情況下起作用。比如我在客戶端用load data infile的方式導(dǎo)入很大的一個(gè)文件到數(shù)據(jù)庫中,然后中途用iptables禁用掉mysql的3306端口,這個(gè)時(shí)候服務(wù)器端該連接狀態(tài)是reading from net,在等待net_read_timeout后關(guān)閉該連接。同理,在程序里面查詢一個(gè)很大的表時(shí),在查詢過程中同樣禁用掉端口,制造網(wǎng)絡(luò)不通的情況,這樣該連接狀態(tài)是writing to net,然后在net_write_timeout后關(guān)閉該連接。slave_net_timeout類似。

The number of seconds to wait for more data from a connection before aborting the read. When the server is reading from the client, net_read_timeout is the timeout value controlling when to abort. When the server is writing to the client, net_write_timeout is the timeout value controlling when to abort

測試:
我創(chuàng)建一個(gè)120M的數(shù)據(jù)文件data.txt。然后登陸到mysql。

mysql -uroot -h 127.0.0.1 -P 3306 --local-infile=1

導(dǎo)入過程設(shè)置iptables禁用3306端口。

iptables -A INPUT -p tcp --dport 3306 -j DROP
iptables -A OUTPUT -p tcp --sport 3306 -j DROP

可以看到連接狀態(tài)為reading from net,然后經(jīng)過net_read_timeout秒后關(guān)閉。

經(jīng)過幾個(gè)實(shí)驗(yàn)可以發(fā)現(xiàn),connect_timeout在握手認(rèn)證階段(authenticate)起作用,interactive_timeout 和wait_timeout在連接空閑階段(sleep)起作用,而net_read_timeout和net_write_timeout則是在連接繁忙階段(query)或者網(wǎng)絡(luò)出現(xiàn)問題時(shí)起作用。

以上是“mysql timeout變量的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI