MySQL 8.0.39:双会话、ReadView 与死锁
统一真实实验入口在 labs/mysql,固定 mysql:8.0.39 / InnoDB。2026-10-23 Docker的8.0.39镜像未运行,用户提供本机MySQL Community 8.4.7,已用 run_local.py --mode tx 实际运行下列核心对照。手工8.0.39协议的版本不变;8.4.7结果详见教材与审计。Python模型不替代真库证据。
- 运行
bash labs/mysql/run.sh setup:专用study_tx中账户1/2余额均100、version1,锁表10/20/30,医生1/2在岗,guard为班次1。完整DDL见 setup.sql。 - 分别打开A/B交互连接,按 sessions.sql 的五组交接执行;同一连接一次粘贴全部文件不能验证并发。每组开始确认
@@transaction_isolation与@@autocommit。 - RR A首次读100,B提交80,A再次普通读预期100、锁定读80、自己扣10后普通读70;RC对照第二次普通读80。移动首次普通读到B提交后,RR也预期80,验证BEGIN不自动定快照。
- RR唯一未命中15可能阻塞B插入15;唯一命中20对照通常不阻塞插入15。观察连接运行
bash labs/mysql/run.sh observe,保存 observe.sql 的索引、锁模式、事务与等待边,不固定物理页号。RC减少间隙锁,但外键/重复键检查例外。 - A条件扣80未提交,B同样扣80等待;A提交后B预期更新0行,立即取ROW_COUNT。当前谓词裁决不能拿较早普通读代替。
- A锁1、B锁2、A申请2等待、B申请1成环;启用死锁检测时预期恰有一个1213,另一方继续。不指定谁被选中;保存最近死锁与完整事务SQL。1205默认通常只回滚语句,需核对
innodb_rollback_on_timeout;应用均先显式回滚再有界重建完整事务。 - 两医生各读在岗2后更新不同医生为0,预期可都提交,暴露写偏差。正确对照:所有写路径先锁同一guard,再以当前锁定读检查在岗集合;不能先读旧快照后排队取guard仍用旧数。
各组结束A/B都显式ROLLBACK,确认无残余事务再重建数据。这里不用 down -v 清理锁,不连接共享业务库。完整讲解及题目回查见 MVCC与锁、诊断恢复。