orderby rand() for update 和 操作字段未加索引 导致mysql死锁

最近在项目上碰到orderby rand() for update导致mysql死锁,不多说,直接上分析过程和截图

1. 使用 下面几个语句查看mysql 的事务和锁的情况

SELECT * FROM information_schema.INNODB_TRX;
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

(1)3595719是我当前运行的事务,3595719阻塞了3595721的提交。

(2)3595721中对3595722和3595727 的两个sql语句中的相关表做了删除或者更新操作,3595722和3595727的sql语句形如

      SELECT * FROM table1 WHERE (index_sync_status = 0) order by RAND() limit 1 for update;

(3)而由于3595722和3595727 是 orderby rand() for update,导致升级为表锁。从而被3595721阻塞了

(4)将3595722和3595727的语句改成如下,解决orderby rand() for update问题

      SELECT id FROM table1 WHERE (index_sync_status = 0) order by RAND() limit 1;

      SELECT * FROM table1 WHERE id = xxx for update ;

(5)发现3595719并没有对3595721中的 content_id = 'e37d57c66e7c4bb2bf7b607eaffa2f2d'进行操作。怀疑是content_id没有索引,导致行锁升级为表锁。添加索引,解决

    ALTER TABLE `table1` ADD INDEX index_content_id (`content_id`);

 

 

posted @ 2023-07-14 15:52  蓬莱寒剑  阅读(132)  评论(0)    收藏  举报