在主库 上,Executed_Gtid_Set 是在本地事务 commit 成功后 才更新到 @@GLOBAL.gtid_executed 里的,不是"binlog 刚写完"就对外可见。
按主库事务链路看:
- 事务执行
- 分配 GTID
- commit 阶段写 binlog,
Gtid_log_event写在事务事件前面 - binlog 持久化
- 存储引擎提交成功
- GTID 加入主库的
@@GLOBAL.gtid_executed SHOW MASTER STATUS/SHOW REPLICA STATUS看到的Executed_Gtid_Set才包含它
结合半同步:
after_sync下,主库是 binlog 已刷盘、事务已发给从库并等 ACK 后,才提交存储引擎 。所以在等待 ACK 的阶段,这个事务虽然已经在主库 binlog 里,也可能已经在从库 relay log 里,但主库本地还没 commit,理论上还不应该出现在主库Executed_Gtid_Set。after_commit下,主库先提交存储引擎,再等从库 ACK;因此主库 commit 完后,Executed_Gtid_Set很快会包含该 GTID,即使半同步 ACK 还没回来。
一句话:主库的 Executed_Gtid_Set 表示"主库已经提交过的 GTID",不是"主库 binlog 已写过的 GTID",也不是"从库已收到的 GTID"。
另一个细节:mysql.gtid_executed 表和 @@GLOBAL.gtid_executed 不完全等价。主库开启 binlog 时,完整实时状态看 @@GLOBAL.gtid_executed / SHOW MASTER STATUS,不要只看 mysql.gtid_executed 表;表里的内容可能要到 binlog rotate、shutdown,或特定版本/引擎路径下才补齐。