本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/server_kill_idle_transaction.html 在上一篇文章里我们写了如何针对InnoDB清理空闲事务《如何杀掉空闲事务》
本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/server_kill_idle_transaction.html
在上一篇文章里我们写了如何针对InnoDB清理空闲事务《如何杀掉空闲事务》,在@sleebin9 的提示下,这个功能不仅可以针对InnoDB,也可以用于所有MySQL的事务引擎。
如何在Server层实现呢,sql/sql_parse.cc的do_command()函数是个好函数,连接线程会循环调用do_command()来读取并执行命令,在do_command()函数中,会调用my_net_set_read_timeout(net, thd->variables.net_wait_timeout)来设置线程socket连接超时时间,于是在这里可以下手。
主要代码:
<span style="color: #0000dd;">830</span> <span style="color: #ff0000; font-style: italic;">/* 831 This thread will do a blocking read from the client which 832 will be interrupted when the next command is received from 833 the client, the connection is closed or "net_wait_timeout" 834 number of seconds has passed 835 */</span> <span style="color: #0000dd;">836</span> <span style="color: #ff0000; font-style: italic;">/* Add For Kill Idle Transaction By P.Linux */</span> <span style="color: #0000dd;">837</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">(</span>thd<span style="color: #000040;">-</span><span style="color: #000080;">></span>active_transaction<span style="color: #008000;">(</span><span style="color: #008000;">)</span><span style="color: #008000;">)</span> <span style="color: #0000dd;">838</span> <span style="color: #008000;">{</span> <span style="color: #0000dd;">839</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">(</span>thd<span style="color: #000040;">-</span><span style="color: #000080;">></span>variables.<span style="color: #007788;">trx_idle_timeout</span> <span style="color: #000080;">></span> <span style="color: #0000dd;">0</span><span style="color: #008000;">)</span> <span style="color: #0000dd;">840</span> <span style="color: #008000;">{</span> <span style="color: #0000dd;">841</span> my_net_set_read_timeout<span style="color: #008000;">(</span>net, thd<span style="color: #000040;">-</span><span style="color: #000080;">></span>variables.<span style="color: #007788;">trx_idle_timeout</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> <span style="color: #0000dd;">842</span> <span style="color: #008000;">}</span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">(</span>thd<span style="color: #000040;">-</span><span style="color: #000080;">></span>variables.<span style="color: #007788;">trx_readonly_idle_timeout</span> <span style="color: #000080;">></span> <span style="color: #0000dd;">0</span> <span style="color: #000040;">&&</span> thd<span style="color: #000040;">-</span><span style="color: #000080;">></span>is_readonly_trx<span style="color: #008000;">)</span> <span style="color: #0000dd;">843</span> <span style="color: #008000;">{</span> <span style="color: #0000dd;">844</span> my_net_set_read_timeout<span style="color: #008000;">(</span>net, thd<span style="color: #000040;">-</span><span style="color: #000080;">></span>variables.<span style="color: #007788;">trx_readonly_idle_timeout</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> <span style="color: #0000dd;">845</span> <span style="color: #008000;">}</span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">(</span>thd<span style="color: #000040;">-</span><span style="color: #000080;">></span>variables.<span style="color: #007788;">trx_changes_idle_timeout</span> <span style="color: #000080;">></span> <span style="color: #0000dd;">0</span> <span style="color: #000040;">&&</span> <span style="color: #000040;">!</span>thd<span style="color: #000040;">-</span><span style="color: #000080;">></span>is_readonly_trx<span style="color: #008000;">)</span> <span style="color: #0000dd;">846</span> <span style="color: #008000;">{</span> <span style="color: #0000dd;">847</span> my_net_set_read_timeout<span style="color: #008000;">(</span>net, thd<span style="color: #000040;">-</span><span style="color: #000080;">></span>variables.<span style="color: #007788;">trx_changes_idle_timeout</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> <span style="color: #0000dd;">848</span> <span style="color: #008000;">}</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">{</span> <span style="color: #0000dd;">849</span> my_net_set_read_timeout<span style="color: #008000;">(</span>net, thd<span style="color: #000040;">-</span><span style="color: #000080;">></span>variables.<span style="color: #007788;">net_wait_timeout</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> <span style="color: #0000dd;">850</span> <span style="color: #008000;">}</span> <span style="color: #0000dd;">851</span> <span style="color: #008000;">}</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">{</span> <span style="color: #0000dd;">852</span> my_net_set_read_timeout<span style="color: #008000;">(</span>net, thd<span style="color: #000040;">-</span><span style="color: #000080;">></span>variables.<span style="color: #007788;">net_wait_timeout</span><span style="color: #008000;">)</span><span style="color: #008080;">;</span> <span style="color: #0000dd;">853</span> <span style="color: #008000;">}</span> <span style="color: #0000dd;">854</span> <span style="color: #ff0000; font-style: italic;">/* End */</span>
大家看明白了吗?其实这是偷梁换柱,本来在这里是要设置wait_timeout的,先判断线程是不是在事务里,就可以转而实现空闲事务的超时。
trx_idle_timeout 控制所有事务的超时,优先级最高
trx_changes_idle_timeout 控制非只读事务的超时
trx_readonly_idle_timeout 控制只读事务的超时
效果:
root@localhost : <span style="color: #66cc66;">(</span>none<span style="color: #66cc66;">)</span> 08:<span style="color: #cc66cc;">39</span>:<span style="color: #cc66cc;">49</span><span style="color: #66cc66;">></span> <span style="color: #993333; font-weight: bold;">set</span> autocommit <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span> ; Query OK<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span> rows affected <span style="color: #66cc66;">(</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">)</span> root@localhost : <span style="color: #66cc66;">(</span>none<span style="color: #66cc66;">)</span> 08:<span style="color: #cc66cc;">39</span>:<span style="color: #cc66cc;">56</span><span style="color: #66cc66;">></span> <span style="color: #993333; font-weight: bold;">set</span> trx_idle_timeout <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">5</span>; Query OK<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span> rows affected <span style="color: #66cc66;">(</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">)</span> root@localhost : <span style="color: #66cc66;">(</span>none<span style="color: #66cc66;">)</span> 08:<span style="color: #cc66cc;">40</span>:<span style="color: #cc66cc;">17</span><span style="color: #66cc66;">></span> <span style="color: #993333; font-weight: bold;">use</span> perf <span style="color: #993333; font-weight: bold;">Database</span> changed root@localhost : perf 08:<span style="color: #cc66cc;">40</span>:<span style="color: #cc66cc;">19</span><span style="color: #66cc66;">></span> <span style="color: #993333; font-weight: bold;">insert</span> <span style="color: #993333; font-weight: bold;">into</span> perf <span style="color: #66cc66;">(</span>info <span style="color: #66cc66;">)</span> <span style="color: #993333; font-weight: bold;">values</span><span style="color: #66cc66;">(</span><span style="color: #ff0000;">'11'</span><span style="color: #66cc66;">)</span>; Query OK<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span> row affected <span style="color: #66cc66;">(</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">)</span> root@localhost : perf 08:<span style="color: #cc66cc;">40</span>:<span style="color: #cc66cc;">26</span><span style="color: #66cc66;">></span> <span style="color: #993333; font-weight: bold;">select</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">from</span> perf; ERROR <span style="color: #cc66cc;">2006</span> <span style="color: #66cc66;">(</span>HY000<span style="color: #66cc66;">)</span>: MySQL server has gone away No connection<span style="color: #66cc66;">.</span> Trying <span style="color: #993333; font-weight: bold;">to</span> reconnect<span style="color: #66cc66;">...</span> Connection id: <span style="color: #cc66cc;">6</span> Current <span style="color: #993333; font-weight: bold;">database</span>: perf <span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+------+</span> <span style="color: #66cc66;">|</span> id <span style="color: #66cc66;">|</span> info <span style="color: #66cc66;">|</span> <span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+------+</span> <span style="color: #66cc66;">|</span> <span style="color: #cc66cc;">7</span> <span style="color: #66cc66;">|</span> aaaa <span style="color: #66cc66;">|</span> <span style="color: #66cc66;">|</span> <span style="color: #cc66cc;">9</span> <span style="color: #66cc66;">|</span> aaaa <span style="color: #66cc66;">|</span> <span style="color: #66cc66;">|</span> <span style="color: #cc66cc;">11</span> <span style="color: #66cc66;">|</span> aaaa <span style="color: #66cc66;">|</span> <span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+------+</span> <span style="color: #cc66cc;">3</span> rows <span style="color: #993333; font-weight: bold;">in</span> <span style="color: #993333; font-weight: bold;">set</span> <span style="color: #66cc66;">(</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">)</span>
完整的patch这里下载:
Note: There is a file embedded within this post, please visit this post to download the file.