事故重现,并且加入一些后期想到的想法作为演义. 今天 mysql 服务器负载过高, 主库上主要是写的操作,首先看有没有锁表的,发现没有.mysql -uroot -e "show processlist"|grep -i 'locked'|wc -l
再看delete,update,insert操作的数量.mysql -uroot -e "show processlist"|grep -i 'delete'|wc -l
mysql -uroot -e "show processlist"|grep -i 'update'|wc -l
mysql -uroot -e "show processlist"|grep -i 'insert'|wc -l
这三个的总数合起来也没超过200, 就这样, mysql 占用的 cpu% 已经到了800%了.
再看下耗时排行(其实应该查看锁表就应该直接看耗时了)mysql -uroot -e "show processlist;" |sort -nr -k6;
发现有很多delete已经快1个小时了还没执行完毕,看来主要是卡在了delete的操作上.
所以我先把线上服务器中执行相同语句的操作都转移写入到文本,不再请求数据,防止相同的操作进来继续堵塞. 然后想 kill 掉那些连接, 于是我想到是不是可以这样来操作:mysql -uroot -e "show processlist;" |grep -i 'delete'|awk '{print $1}'|xargs mysql -uroot -e 'kill (xxx)'
但是awk得到的$1怎么传给后面的做参数呢,因为末尾还有一个单引号.然后又想到这样, 发现也还是不行, 语法有误.mysql -uroot -e "show processlist;" |grep -i 'delete'|awk '{print "mysql -uroot -e \'kill "$1"\' }'|sh
正确的做法:#最后我们运维明哥,给我的语句是:
mysql -uroot -e "show processlist;" |grep -i 'delete'|awk '{print "mysql -uroot -e " "\047" "kill " $1"\047;" }'|sh
#志华老师提醒可以像 C 语言一样用`printf`,我写了下,还没来的及时试验
mysql -uroot -e "show processlist;" |grep -i 'delete'|awk '{printf "mysql -uroot -e \"kill %d;\"",$1}'|sh