事故重现,并且加入一些后期想到的想法作为演义. 今天 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