在MySQL的客户端中通过show [full] processlist可以看到当前所有线程,以及线程的状态,当然也包括执行中的sql,但是显示的语句不完全,并且有很多空闲线程会造成干扰。
这里要介绍一个非常好用的开源工具innotop(sourceforge已经被墙了,要过去先找梯子),由于是用perl写的,所以需要安装相关的perl模块,包括DBI,DBD::mysql,Term::ReadKey和Time::HiRes,这些模块都可以到CPAN找到。
用innotop的Q模式则可以完美的解决获取当前运行的SQL的问题。innotop -m Q 或者innotop进入后再按shift+q进入Query list模式:
Query List (? for help) mysql01, 75+03:16:16, 774.20 QPS, 83 thd, 5.1.24-rc-log CXN When Load QPS Slow QCacheHit KCacheHit BpsIn BpsOut my120 Now 0.00 774.20 0 40.22% 100.00% 207.98k 1.46M my120 Total 0.00 212.69 2 29.70% 100.00% 56.90k 402.15k CXN Cmd ID User Host DB Time Query mysql01 Query 20936 poster 192.168.1.1 poster 00:00 select a.poster_id, a.pic_id, a.gmt_create, a.gmt_modified, a.url, a.no
然后按e并输入thread ID显示执行计划或者按f显示完整sql语句,或者按o显示系统优化过的语句(需要MySQL的版本支持EXPLAIN EXTENDED)。个人感觉,还是e最有用,其他两个选项,则有点鸡肋了。
Query List (? for help) mysql01, 75+03:16:16, 774.20 QPS, 83 thd, 5.1.24-rc-log EXPLAIN PARTITIONS select a.poster_id, a.pic_id, a.gmt_create, a.gmt_modified, a.url, a.notes, a.type, a.indexed, a.user_id, a.user_nick, b.pic_path from poster.poster_pic a inner join poster.picture b on (a.pic_id = b.id) where a.poster_id = 3390 order by a.indexed ______________ Sub-Part 1 ______________ ________ Sub-Part 1 ________ Select Type: SIMPLE Select Type: SIMPLE Table: a Table: b Partitions: Partitions: Type: ref Type: eq_ref Poss. Keys: PRIMARY Poss. Keys: PRIMARY Index: PRIMARY Index: PRIMARY Key Length: 4 Key Length: 8 Index Ref: const Index Ref: poster.a.PIC_ID Row Count: 14 Row Count: 1 Special: Using where; Using filesort Special: Press e to explain, f for full query, o for optimized query
Query List (? for help) mysql01, 75+03:16:16, 774.20 QPS, 83 thd, 5.1.24-rc-log select a.poster_id, a.pic_id, a.gmt_create, a.gmt_modified, a.url, a.notes, a.type, a.indexed, a.user_id, a.user_nick, b.pic_path from poster.poster_pic a inner join poster.picture b on (a.pic_id = b.id) where a.poster_id = 3390 order by a.indexed Press e to explain, f for full query, o for optimized query
Query List (? for help) mysql01, 75+03:16:16, 774.20 QPS, 83 thd, 5.1.24-rc-log select a.poster_id, a.pic_id, a.gmt_create, a.gmt_modified, a.url, a.notes, a.type, a.indexed, a.user_id, a.user_nick, b.pic_path from poster.poster_pic a inner join poster.picture b on (a.pic_id = b.id) where a.poster_id = 3390 order by a.indexed Note: select `poster`.`a`.`POSTER_ID` AS `poster_id`,`poster`.`a`.`PIC_ID` AS `pic_id`,`poster`.`a`.`GMT_CREATE` AS `gmt_create`, `poster`.`a`.`GMT_MODIFIED` AS `gmt_modified`, `poster`.`a`.`URL` AS `url`,`poster`.`a`.`NOTES` AS `notes`, `poster`.`a`.`TYPE` AS `type`,`poster`.`a`.`INDEXED` AS `indexed`, `poster`.`a`.`USER_ID` AS `user_id`,`poster`.`a`.`user_nick` AS `user_nick`,`poster`.`b`.`PIC_PATH` AS `pic_path` from `poster`.`poster_pic` `a` join `poster`.`picture` `b` where ((`poster`.`b`.`ID` = `poster`.`a`.`PIC_ID`) and (`poster`.`a`.`POSTER_ID` = 3390)) order by `poster`.`a`.`INDEXED` Press e to explain, f for full query, o for optimized query
那么innotop是从哪里取的数据呢?应该是通过information_schema.processlist来获得完整的sql语句,并且根据COMMAND来过滤掉空闲线程的。
mysql> desc information_schema.processlist; +---------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+-------------+------+-----+---------+-------+ | ID | bigint(4) | NO | | 0 | | | USER | varchar(16) | NO | | | | | HOST | varchar(64) | NO | | | | | DB | varchar(64) | YES | | NULL | | | COMMAND | varchar(16) | NO | | | | | TIME | bigint(7) | NO | | 0 | | | STATE | varchar(64) | YES | | NULL | | | INFO | longtext | YES | | NULL | | +---------+-------------+------+-----+---------+-------+ 8 rows in set (0.00 sec)