1MySQL 数据库当出现慢查询, 是比较危险的, 一旦有其他的 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/bash
- for i in `mysql -Bse 'show full processlist' | grep -i select |grep -i "Waiting | awk'{print $1}'`
- do
- mysql -Bse "kill $i"
- done
show processlist 的 command 的状态有很多, 其中 Query 代表正在执行的命令
- Query : The thread is executing a statement.
- cat killLongQuerySession.sh
- #!/bin/bash
- executetime=(`mysql -Bse 'show processlist'| grep 'Query'|awk '{print $6" "$1}'|sort -rn|head -1`) #第 6 列是运行时间, 第一列为 session id
- time=${executetime[0]}
- id=${executetime[1]}
- while :
- do
- maxtime=300
- if [ $time -gt $maxtime ] ; then
- echo $time $id>> /tmp/killqueryid.log
- mysql -Bse "kill $id"
- #else
- # echo $time $id
- fi
- sleep 10 #睡眠 10s
- done
来源: http://www.linuxidc.com/Linux/2018-03/151304.htm