久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

MySQL中參數wait

161次閱讀
沒有評論

共計 10256 個字符,預計需要花費 26 分鐘才能閱讀完成。

行業資訊    
數據庫    
MySQL 數據庫    
MySQL 中參數 wait_timeout 和 interactive_timeout 以及空閑超時的實現方法是什么

本篇內容介紹了“MySQL 中參數 wait_timeout 和 interactive_timeout 以及空閑超時的實現方法是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓丸趣 TV 小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

一、參數意思

這里簡單解釋一下兩個參數含義如下:

interactive_timeout:The number of seconds the server waits for activity on an interactive connection before closing
it. An interactive client is defined as a client that uses the CLIENT_INTERACTIVE option to mysql_real_connect()

wait_timeout: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())

他們都是 session/global 級別的,簡單的說前者用于描述交互式的客戶端的空閑超時,后者用于非交互式的客戶端的空閑超時,但是這里也揭示了,如果是交互式客戶端連接的 session 那么 wait_timeout 將被 interactive_timeout 覆蓋掉,換句話說如果是非交互式的客戶端連接的 session 將不會使用 interactive_timeout 覆蓋掉 wait_timeout,也就是 interactive_timeout 沒有任何作用了。

二、參數內部表示

interactive_timeout:

static Sys_var_ulong Sys_interactive_timeout( vio_io_wait  interactive_timeout ,  The number of seconds the server waits for activity on an interactive  
  connection before closing it ,
 SESSION_VAR(net_interactive_timeout), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1));

wait_timeout:

static Sys_var_ulong Sys_net_wait_timeout(  wait_timeout ,  The number of seconds the server waits for activity on a  
  connection before closing it ,
 SESSION_VAR(net_wait_timeout), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT)), DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1));

我們可以看到內部而言參數 interactive_timeout 表示為 net_interactive_timeout,wait_timeout 表示為 net_wait_timeout。

三、interactive_timeout 覆蓋 wait_timeout

實際上這個操作只會在用戶登陸的時候才出現函數對應 server_mpvio_update_thd,如下:

server_mpvio_update_thd(THD *thd, MPVIO_EXT *mpvio) do_command
 thd- max_client_packet_length= mpvio- max_client_packet_length; if (mpvio- protocol- has_client_capability(CLIENT_INTERACTIVE)) // 這里做判斷
 thd- variables.net_wait_timeout= thd- variables.net_interactive_timeout;// 這里覆蓋 

這里我們可以明確看到有覆蓋操作,并且我們也能看到這里的 if 條件是如果是 CLIENT_INTERACTIVE 類型的客戶端連接才會做覆蓋。

棧幀如下:

#0 server_mpvio_update_thd (thd=0x7ffe7c012940, mpvio=0x7fffec0f6140) at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/auth/sql_authentication.cc:2014#1 0x0000000000f01787 in acl_authenticate (thd=0x7ffe7c012940, command=COM_CONNECT, extra_port_connection=false)
 at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/auth/sql_authentication.cc:2246#2 0x0000000001571149 in check_connection (thd=0x7ffe7c012940, extra_port_connection=false)
 at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/sql_connect.cc:1295#3 0x00000000015712dc in login_connection (thd=0x7ffe7c012940, extra_port_connection=false)
 at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/sql_connect.cc:1352#4 0x0000000001571bfe in thd_prepare_connection (thd=0x7ffe7c012940, extra_port_connection=false)
 at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/sql_connect.cc:1516#5 0x000000000170e642 in handle_connection (arg=0x6781c30) at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/conn_handler/connection_handler_per_thread.cc:306

那么我們這里可以得到一個結論,只在登陸的時候會判斷連接是否是交互式的,如果是則覆蓋掉參數 wait_timeout,但是一旦連接后將不會發生覆蓋操作,即便我們再次修改 interactive_timeout 的值也不會覆蓋,后面我們會看到實際上生效的參數只有 wait_timeout。

四、超時的實現

實際上每次執行任何一個命令都會做一次 wait_timeout 值的重新檢查和賦值給網絡 read_timeout 值。在函數 do_command 中我們可以發現 my_net_set_read_timeout(net, thd- get_wait_timeout()); 步驟,這個步驟就是將我們的 wait_timeout 賦值給網絡 read_timeout 值,其中包含片段

 if (net- read_timeout == timeout) // 如果 read_timeout 和 wait_timeout 相等
 DBUG_VOID_RETURN;// 不需要做操作直接 return
 net- read_timeout= timeout;// 否則進行賦值。 if (net- vio)
 vio_timeout(net- vio, 0, timeout);// 這里會進行 net- vio.read_timeout 的賦值 

執行完這個步驟后 wait_timeout 就生效了,然后就會執行命令,執行完命令后,整個線程會再次回到 do_command 函數,再做一次 my_net_set_read_timeout 函數生效其中的 wait_timeout 參數,中并且堵塞接受命令 (后面可以看到是 poll 實現的),這個時候 wait_timeout 就起作用了。整個棧幀如下:

#0 vio_io_wait (vio=0x7ffe7c015520, event=VIO_IO_EVENT_READ, timeout=10000) at /root/mysqlall/percona-server-locks-detail-5.7.22/vio/viosocket.c:1119#1 0x0000000001e4d5f6 in vio_socket_io_wait (vio=0x7ffe7c015520, event=VIO_IO_EVENT_READ) at /root/mysqlall/percona-server-locks-detail-5.7.22/vio/viosocket.c:116#2 0x0000000001e4d6d2 in vio_read (vio=0x7ffe7c015520, buf=0x7ffe7c061c10  \001 , size=4) at /root/mysqlall/percona-server-locks-detail-5.7.22/vio/viosocket.c:171#3 0x00000000014c6ceb in net_read_raw_loop (net=0x7ffe7c028440, count=4) at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/net_serv.cc:672#4 0x00000000014c6ec2 in net_read_packet_header (net=0x7ffe7c028440) at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/net_serv.cc:756#5 0x00000000014c6fcb in net_read_packet (net=0x7ffe7c028440, complen=0x7fffec0c5c58) at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/net_serv.cc:822#6 0x00000000014c715e in my_net_read (net=0x7ffe7c028440) at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/net_serv.cc:899#7 0x00000000014de010 in Protocol_classic::read_packet (this=0x7ffe7c027bf8) at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/protocol_classic.cc:808#8 0x00000000014de514 in Protocol_classic::get_command (this=0x7ffe7c027bf8, com_data=0x7fffec0c5d70, cmd=0x7fffec0c5d98)
 at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/protocol_classic.cc:965#9 0x00000000015c5699 in do_command (thd=0x7ffe7c0268e0) at /root/mysqlall/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:960

最終會調入 vio_io_wait 函數,如下是其中的部分片段,我們可以清楚看到實際上所謂的空閑超時實際上就是我們的 pool 實現的。

switch ((ret= poll( pfd, 1, timeout))) 
 { case -1: /* On error, -1 is returned. */
 break; case 0: /*
 Set errno to indicate a timeout error.
 (This is not compiled in on WIN32.)
 */
 errno= SOCKET_ETIMEDOUT; break; default: /* Ensure that the requested I/O event has completed. */
 DBUG_ASSERT(pfd.revents   revents); break;
 }

因此整個步驟就是

loop

做 wait_timeout 參數檢查并且賦值。

堵塞接受命令由 poll 函數實現,通過 poll 函數的超時參數也實現了空閑等待超時。(如果不發送命令就堵塞在這里)

命令來到退出堵塞。

再次做 wait_timeout 參數檢查并且賦值。

執行命令。

goto loop

五、測試

我這里就用 mysql 客戶端和 pymysql 進行交互和非交互連接的測試。

交互式 mysql 客戶端會話 interactive_timeout 參數覆蓋 wait_timeout 參數

mysql  show variables like  wait_timeout% 
+---------------+-------+| Variable_name | Value |
+---------------+-------+
| wait_timeout | 28800 |+---------------+-------+1 row in set (0.02 sec)
mysql  show variables like  interactive_timeout 
+---------------------+-------+| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 28800 |+---------------------+-------+1 row in set (0.01 sec)
mysql  set global interactive_timeout = 20;
Query OK, 0 rows affected (0.00 sec)
mysql  exit
[root@gp1 log]# /mysqldata/mysql3340/bin/mysqlWelcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6Server version: 5.7.22-22-debug-log Source distribution
Copyright (c) 2009-2018 Percona LLC and/or its affiliates
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type  help;  or  \h  for help. Type  \c  to clear the current input statement.
mysql  show variables like  interactive_timeout 
+---------------------+-------+| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 20 |+---------------------+-------+1 row in set (0.01 sec)
mysql  show variables like  wait_timeout 
+---------------+-------+| Variable_name | Value |
+---------------+-------+
| wait_timeout | 20 |+---------------+-------+1 row in set (0.02 sec)

交互式 mysql 客戶端會話登陸期間修改 interactive_timeout 不生效,更改 wait_timeout 生效。

mysql  show variables like  interactive_timeout 
+---------------------+-------+| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 28800 |+---------------------+-------+1 row in set (0.02 sec)
mysql  show variables like  wait_timeout 
+---------------+-------+| Variable_name | Value |
+---------------+-------+
| wait_timeout | 28800 |+---------------+-------+1 row in set (0.02 sec)
mysql  set interactive_timeout=5;
Query OK, 0 rows affected (0.00 sec)
mysql  show variables like  wait_timeout 
+---------------+-------+| Variable_name | Value |
+---------------+-------+
| wait_timeout | 28800 |+---------------+-------+1 row in set (0.01 sec)
mysql  show variables like  interactive_timeout 
+---------------------+-------+| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 5 |+---------------------+-------+1 row in set (0.02 sec)
等待 5 秒,并未生效
mysql  select sysdate();
+---------------------+| sysdate() |+---------------------+| 2019-02-28 17:24:29 |+---------------------+1 row in set (0.00 sec)
mysql  set wait_timeout=5;
Query OK, 0 rows affected (0.00 sec)
等待 5 秒   發現斷開了
mysql  show variables like  wait_timeout 
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 10

使用 python 連接非交互式客戶端 interactive_timeout 參數不會覆蓋 wait_timeout 參數

我們可以簡單的寫一個 python 腳本如下:

import socketimport pymysql.cursorsimport psutilimport subprocess
mysql_con = {host : 192.168.99.95 , port :3340, user : pycon , passwd : gelc123 , db : test}def main():
 sqlwait =  show variables like  wait_timeout 
 sqlinter =  show variables like  interactive_timeout 
 sql_c_inter =  set global interactive_timeout=10 
 connect = pymysql.Connect(host=mysql_con[ host], port=mysql_con[port], user=mysql_con[user],
 passwd=mysql_con[passwd], db=mysql_con[db])
 cursor = connect.cursor() ## 查看初始值
 cursor.execute(sqlwait)
 ret_wait = cursor.fetchone()
 cursor.execute(sqlinter)
 ret_inter = cursor.fetchone()
 print(before change: {} .format(ret_wait+ret_inter)) ## 更改值
 cursor.execute(sql_c_inter)
 connect.close()## 關閉連接
 ## 重新登陸開啟連接
 connect = pymysql.Connect(host=mysql_con[ host], port=mysql_con[port], user=mysql_con[user],
 passwd=mysql_con[passwd], db=mysql_con[db])
 cursor = connect.cursor()
 cursor.execute(sqlwait)
 ret_wait = cursor.fetchone()
 cursor.execute(sqlinter)
 ret_inter = cursor.fetchone()
 print(after change: {} .format(ret_wait+ret_inter)) ## 恢復值
 sql_c_inter =  set global interactive_timeout=28800 
 cursor.execute(sql_c_inter)
 connect.close()# 關閉連接 ## 程序開始 if __name__ ==  __main__ :
 main()

得到的測試結果如下:

before change: (wait_timeout ,  28800 ,  interactive_timeout ,  28800)
after change: (wait_timeout ,  28800 ,  interactive_timeout ,  10)

如果是交互是客戶端會話的話 wait_timeout 也應該是 10。

“MySQL 中參數 wait_timeout 和 interactive_timeout 以及空閑超時的實現方法是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注丸趣 TV 網站,丸趣 TV 小編將為大家輸出更多高質量的實用文章!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-26發表,共計10256字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 江口县| 茌平县| 普陀区| 定襄县| 乌恰县| 陵川县| 禹州市| 荣昌县| 江陵县| 精河县| 彩票| 佛山市| 都兰县| 夹江县| 南召县| 南开区| 麟游县| 晋宁县| 开化县| 化隆| 平舆县| 渝北区| 新巴尔虎右旗| 永善县| 海盐县| 眉山市| 长宁区| 海南省| 屏东县| 安图县| 靖安县| 文昌市| 蒙阴县| 兴业县| 东乡族自治县| 颍上县| 集安市| 阿拉善右旗| 灌南县| 金山区| 拉孜县|