mysql双主复制天然不保证事务顺序一致性,两主库独立写入、各自提交并生成不同source_uuid的gtid,复制后发生覆盖而非合并;auto_increment_offset仅防id冲突,不防业务层冲突;gtid仅加速暴露冲突,不参与检测或仲裁;真正防冲突依赖应用层写路由收敛。

双主写入天然不保证事务顺序一致性
MySQL双主复制本身不提供跨节点的并发控制,两个主库各自独立接受写请求、生成事务、提交并广播 binlog。当两个库同时修改同一行(比如 UPDATE order SET status = 'shipped' WHERE id = 123),它们互不知情,都会成功提交,并各自生成不同 source_uuid 的 GTID。复制线程拉取对方事务后照常执行——结果不是合并,而是后到者覆盖前到者。
auto_increment_offset 只防 ID 冲突,不防业务冲突
很多人以为配好 auto_increment_increment 和 auto_increment_offset 就“安全”了,其实它只解决自增主键重复问题。以下场景完全不受保护:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
-
INSERT INTO users (email) VALUES ('a@b.com')在 A 和 B 同时执行 → 唯一键冲突报错ERROR 1062 -
DELETE FROM cart WHERE user_id = 1001和UPDATE cart SET qty = 5 WHERE user_id = 1001并发发生 → 一个删掉行,另一个更新失败或跳过 - 无条件更新:
UPDATE account SET balance = balance + 100→ 双主各自读旧值、加100、写回,最终只加了一次
GTID 不是冲突解决器,只是冲突加速暴露器
gtid_mode = ON 的作用是让事务可追溯、位点管理更可靠,但它不参与任何冲突检测或仲裁逻辑。两个主库生成的 GTID 虽然全局唯一,但 MySQL SQL 线程不会比对“这个事务是否已在本地执行过”,也不会拒绝执行“语义上冲突”的事务。反而因为 GTID 强制严格有序,一旦遇到 Duplicate entry 或 Can't find record,复制会立刻中断,而不是像传统模式那样可能静默跳过。
从库误写入在双主下更难察觉
单主架构中,read_only = ON 能有效拦截误操作;但在双主里,每个节点既是主又是从,read_only 必须设为 OFF 才能写入。这意味着任何应用路由错误、配置漏改、甚至运维手抖连错实例,都会直接污染数据,且冲突往往延迟暴露——等另一台主库同步过来才发现主键撞了、行丢了、字段值对不上。
user_id)的所有写必须固定打到同一主库。这个逻辑不在数据库内,而在客户端、Proxy 或服务层。漏掉这点,再细的 server-id 或再严的 enforce_gtid_consistency 都只是给崩溃铺上缓冲垫。










