1、MySQL数据库当出现慢查询,是比较危险的,一旦有其他的DDL操作,可能会造成整个数据库的等待

可以分以下几种情况:

当表是MyiSAM表,对表有慢查询,不阻塞Select,对该表的其他DML,DDL操作都会被阻塞,比如出现Wating for table level lock,数据库中一定不能还存在MyiSAM表

当表是Innodb表,当表上有慢查询,不阻塞Select 和DML,其他的DDL操作都会被阻塞,比如出现waiting for table metadata lock


综上,当数据库中存在慢查询时,是比较危险的,当执行备份,create index ,alter table , flush table 等操作时就会造成数据库的等待


解决办法:

1、对数据库中执行时间较长的Select进行监控,并及时报警

2、如果允许的话,写脚本,发现较长的select语句,直接kill,并记录日志中




-B, --batch Don't use history file. Disable interactive behavior.

-s, --silent Be more silent. Print results with a tab as separator,each row on new line.

-e, --execute=name Execute command and quit. (Disables --force and historyfile.)


#如果数据库中当前有大量的select,可以过滤掉,只kill waiting的

cat killWaitSession.sh

#!/bin/bashforiin`mysql-Bse'showfullprocesslist'|grep-iselect|grep-i"Waiting|awk'{print$1}'`domysql-Bse"kill$i"done



show processlist的command的状态有很多,其中Query代表正在执行的命令


Query : The thread is executing a statement.


cat killLongQuerySession.sh

#!/bin/bashexecutetime=(`mysql-Bse'showprocesslist'|grep'Query'|awk'{print$6""$1}'|sort-rn|head-1`)#第6列是运行时间,第一列为sessionidtime=${executetime[0]}id=${executetime[1]}while:domaxtime=300if[$time-gt$maxtime];thenecho$time$id>>/tmp/killqueryid.logmysql-Bse"kill$id"#else#echo$time$idfisleep10#睡眠10sdone



按MySQL中执行时间反向排序

mysqladminprocesslist--verbose|grep'Query'|awk-F"|"'{print$7$2$9}'|sort-rn-k1


参考:

https://blog.51cto.com/jim123/1836712

https://dev.mysql.com/doc/refman/5.7/en/show-processlist.html

https://dev.mysql.com/doc/refman/5.7/en/thread-commands.html