锁与事务

谁卡着

SELECT * FROM performance_schema.data_locks;
SELECT * FROM performance_schema.data_lock_waits;
SELECT * FROM information_schema.innodb_trx;

旧习惯里的 SHOW ENGINE INNODB STATUS 仍能看最近死锁。把输出里的账号、表名脱敏后再存。

隔离级别

SELECT @@transaction_isolation;

可重复读下,InnoDB 用 next-key 减少幻读,间隙锁会让「扫到的空隙」也被锁住。SQL 写得宽,锁就宽。

死锁

InnoDB 会选代价低的一边回滚。应用要能重试,而不是把死锁当实例故障。减少死锁的方向:

  • 同样的访问顺序
  • 索引让更新精准落到行
  • 缩短事务
  • 避免一条 SQL 扫太多行再更新
SHOW VARIABLES LIKE 'innodb_deadlock_detect';
SHOW VARIABLES LIKE 'innodb_lock_wait_timeout';

注意

SELECT ... FOR UPDATE 会锁。报表会话开了它,业务更新就会排队。连接池里未提交事务等于隐形锁。

参考:InnoDB Locking