周梦康 发表于 2015-05-25 3402 次浏览 标签 : LinuxMysqlawkdba

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

评论列表