作者简介:高鹏,笔名八怪。《深入理解MySQL主从原理》图书作者,同时运营个人公众号“MySQL学习”,持续分享遇到的有趣case以及代码解析!
一、问题来源
今天有个朋友问我如果判断MySQL连接是交互式还是非交互式,我翻了一下没翻到,我们先来看看什么是交互式和非交互式吧。我们知道MySQL连接有交互式和非交互式,比如典型的mysql客户端就是交互式的,而程序连接一般为非交互式。那么如何知道到底是mysql客户端的连接还是程序的连接呢。我们单从show processlist中好像并不能看出来。我也稍微找了一下似乎没有找到更好的视图。
但是我认为这个还是比较有用,通常kill的时候我们需要判定这个连接到底是程序的连接还是mysql客户端的连接(当然可以通过IP等判断),当然如果为mysql客户端的连接通常为DBA的维护连接。当然这个地方稍微修改代码下应该就可以了,但是现有当前情况下如何判断呢?下面我们来想想如何变通的得到结果。
二、如果变通的判断
我觉得只能从我们现有的2个参数interactive_timeout和wait_timeout来判定了,这里有个小知识。对于任何连接来讲都是wait_timeout生效的(poll API的timeout参数实现)。interactive_timeout就是在连接的时候判断,如果是交互式连接就用interactive_timeout替换掉wait_timeout,那么我们可以知道如下:
- 交互式连接interactive_timeout == wait_timeout
- 非交互式interactive_timeout 和 wait_timeout没有关系
我们就利用这一点,默认的两个参数都是28800,我们就修改参数interactive_timeout为28700,wait_timeout保持默认28800这也不会影响什么。
然后我们利用performance_schema.variables_by_thread来观察会话级别的参数,如下:
- 如果会话参数中interactive_timeout == wait_timeout且为28700 那么为交互式
- 如果会话参数中interactive_timeout != wait_timeout一个为28800一个为28700 则为非交互式
如下语句可以判断
select b.processlist_id,a.VARIABLE_NAME,a.VARIABLE_VALUE,b.name from
performance_schema.variables_by_thread a ,performance_schema.threads b
where a.THREAD_ID=b.THREAD_ID and VARIABLE_NAME in('wait_timeout','interactive_timeout');
当然这个结果你也可以在封装一层后直接判断出是交互式还是非交互式连接。
三、测试
截图如下:
我们看到如下:
- session 2:为交互式,因为两个参数均为28700,这是我本地的mysql客户端的连接
- session 3:为非交互式,因为两个参数一个为28800一个为28700,这是dump线程
- session 4,5:为非交互式,因为两个参数一个为28800一个为28700,这是我用pymysql连接的
- session 6:为交互式,因为两个参数均为28700,这是我mysql客户端远端链接的
另外如果有其他的判断的方法也请后台留言告知我,谢谢!因为这个方法需要修改现有参数还是美中不足的。
四、其他小知识分享
最后分享最近看到一个有意思的东西,我们知道C通过GCC编译后得到的可执行文件在linux默认叫做a.out,为什么叫a.out,不叫b.out呢?原来这是有历史的如下:
极客时间《深入C语言和程序运行原理》笔记: “a.out”全名叫做“Assembler Output”,是Unix诞生早期的可执行文件的格式。这个名称来源于 Unix 系统作者 Ken Thompson 最早为 PDP-7 微型计算机编写的汇编器的默认输出文件名。至今,这个名称还是某些编译器(比如 GCC)在创建可执行文件时的默认文件名。