美文网首页我爱编程
MySQL - 一次锁表排查

MySQL - 一次锁表排查

作者: 爱蛇 | 来源:发表于2018-05-28 18:56 被阅读0次

    最近遇到单条更新SQL语句一直报超时:

    update where id=x
    

    原因是有一个事务,因为开发机器上不正常中断程序,导致没有提交。

    先从mysql进程下手

    show full processlist;
    或者
    select * from information_schema.`PROCESSLIST` where db='xxx'
    

    查看有没有DEADLOCK 的进程。
    结果发现没有一条记录是DEADLOCK的。
    (实际上有一个进程显示为SLEEP, 是其中一个一直没有提交事务的进程)

    再从innodb状态下手

    可查看一共有多少个锁在等待

    show status like 'innodb%';
    
    Innodb_row_lock_waits   表示正在等待的锁
    

    再再从innodb 状态下手

    show engine innodb status
    

    配合表使用情况,掌握当前锁表情况

    show open tables from xxx_db;
    

    查看关于Innodb三张重要的表:

    show tables from  information_schema like 'INNODB%';
    

    主要有三张表:

    1. INNODB_LOCKS
    2. INNODB_TRX
    3. INNODB_LOCK_WAITS

    查看未提交的事务

    查看具体事务列表

    select * from information_schema.innodb_trx;
    

    发现有一条记录,有一个字段 tx_thread_id记录着事务对应的进程id。

    回到show processlist;查看这个进程id,发现显示的状态为SLEEP。

    杀掉进程:

    kill {未提交事务对应的进程id}
    

    最后更新语句正常执行了。

    备注

    show processlist; 里显示的进程,虽然没有显示DEADLOCK,
    但不能证明要更新的id 没有被独占。
    出现DEADLOCK 应该是多个事务里互相请求 X锁才会,而在这个情况只是一个事务一直没有提交,而另外一个事务在请求X锁,所以进程显示成了SLEEP。


    最后发现是有人在自己的开发机器上,强行终端未提交事务的程序,导致连接断开了,但事务一直在挂起。

    相关文章

      网友评论

        本文标题:MySQL - 一次锁表排查

        本文链接:https://www.haomeiwen.com/subject/vrxnjftx.html