今天把老服务迁到新买的天翼云服务器上,除了操作系统和docker版本不一样,其它都是一样的,用户收银和开台,交接班都有问题,
对于数据库更新一个只有几千条数据的表都会超时回滚。这种一般都是事务死锁造成的。
比如用户“交接班”的时候只是更新一个 update es_shop_mac set status=2 where mac_no='2324erffsadf', 通过navicat都一直卡,直到超时。
排查步骤:
SET GLOBAL innodb_status_output_locks = ON;
2,执行 SHOW ENGINE INNODB STATUS\G,观察 TRANSACTIONS 部分会显示更详细的锁信息。
执行 show engine innodb status后,如下:
---TRANSACTION 9535990, ACTIVE 3857 sec
6 lock struct(s), heap size 1136, 4 row lock(s), undo log entries 1
MySQL thread id 9987, OS thread handle 140192376829504, query id 393795 172.18.0.10 wetool_admin_pro
TABLE LOCK table `wetool`.`pay_order_sxf` trx id 9535990 lock mode IX
RECORD LOCKS ... # 持有 pay_order_sxf 表的行锁
---TRANSACTION 9520571, ACTIVE 5469 sec
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 718, OS thread handle 140192498869824, query id 346034 172.18.0.6 wetool_admin_pro
TABLE LOCK table `wetool`.`es_shop_mac` trx id 9520571 lock mode IX
RECORD LOCKS ... # 持有 es_shop_mac 表的行锁
问题:
事务 9520571 已活跃 5469 秒(约 1.5 小时),未提交,且持有 es_shop_mac 表的 IX 锁(意向排他锁) 和 行级 X 锁(排他锁)。
事务 9535990 持有 pay_order_sxf 和 order_offline 表的锁,同样未提交。
影响:
当其他会话尝试修改 es_shop_mac 表的同一行或需要升级锁时,会被这两个事务阻塞,导致超时。
IX 锁与 X 锁的互斥性:
IX 锁(意向排他锁)表示事务意图在表中某些行上设置 X 锁。
如果事务 A 持有某行的 X 锁,事务 B 尝试修改同一行时会被阻塞,直到事务 A 提交或回滚。
你的 UPDATE 操作:
当执行 UPDATE es_shop_mac SET status=2 WHERE mac_no='...' 时,需要获取对应行的 X 锁。
由于事务 9520571 已长期持有这些锁,你的操作被迫等待,最终触发锁超时(innodb_lock_wait_timeout 默认 50 秒)。
三,监控长事务
通过以下 SQL 定期监控活跃事务:
SELECT * FROM information_schema.INNODB_TRX
WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 60; -- 查找运行超过 60 秒的事务
根据 MySQL thread id 查找事务来源:
SELECT * FROM performance_schema.threads
WHERE PROCESSLIST_ID = 718; -- 替换为实际 thread id
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!