架構模式對比
| 模式 | 寫入節點 | 同步方向 | 衝突風險 | 適用場景 |
| 單向主從 | 1 個 | 單向 | 無 | 讀寫分離、報表、備份 |
| 雙主 (雙向) | 2 個 (同時寫) | 雙向 | **高** (主鍵衝突、數據覆蓋) | 雙活數據中心、就近寫入 |
| 主主 + 只寫一邊 | 1 個活躍 | 雙向 | 低 (故障切換備用) | 高可用、無感切換 |
**本文重點:雙主 (雙向複製) 配置與防衝突。**
版本兼容原則
- **從庫版本 ≥ 主庫版本** (向上兼容)。
- 推薦**同主版本** (如均 5.7.3x / 8.0.3x) 避免語法/函數/系統表差異。
- 跨大版本複製 (5.7 → 8.0) 需經過嚴格測試。
核心配置 (兩節點對稱)
Node A (192.168.1.10) /etc/my.cnf
[mysqld]
server-id = 10
log-bin = mysql-bin
log-slave-updates = 1 # 關鍵:將從庫接收的事務寫入自身 binlog,傳遞給對端
binlog_format = ROW # 強烈推薦:減少非確定性函數導致的不一致
sync_binlog = 1
gtid_mode = ON # 5.6+ 推薦 GTID
enforce_gtid_consistency = ON
# 雙向複製過濾 (按業務庫)
binlog-do-db = biz_db
replicate-do-db = biz_db
replicate-ignore-db = mysql,information_schema,performance_schema,sys
# 防衝突核心:自增偏移
auto_increment_increment = 2
auto_increment_offset = 1 # Node A 生成 1,3,5,7...
Node B (192.168.1.20) /etc/my.cnf
[mysqld]
server-id = 20
log-bin = mysql-bin
log-slave-updates = 1
binlog_format = ROW
sync_binlog = 1
gtid_mode = ON
enforce_gtid_consistency = ON
binlog-do-db = biz_db
replicate-do-db = biz_db
replicate-ignore-db = mysql,information_schema,performance_schema,sys
auto_increment_increment = 2
auto_increment_offset = 2 # Node B 生成 2,4,6,8...
建立雙向複製賬號
-- Node A
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.20' IDENTIFIED BY 'strong_pass';
-- Node B
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.10' IDENTIFIED BY 'strong_pass';
啟動雙向同步 (GTID 模式)
-- Node A
CHANGE MASTER TO MASTER_HOST='192.168.1.20', MASTER_USER='repl', MASTER_PASSWORD='strong_pass', MASTER_AUTO_POSITION=1;
START SLAVE;
-- Node B
CHANGE MASTER TO MASTER_HOST='192.168.1.10', MASTER_USER='repl', MASTER_PASSWORD='strong_pass', MASTER_AUTO_POSITION=1;
START SLAVE;
驗證與監控
SHOW SLAVE STATUS\G;
-- 關鍵:Slave_IO_Running=Yes, Slave_SQL_Running=Yes, Seconds_Behind_Master=0
-- GTID: Retrieved_Gtid_Set, Executed_Gtid_Set 對比
防衝突深度防禦 (除 auto_increment 外)
| 衝突類型 | 風險 | 緩解措施 |
| 唯一鍵衝突 (非 PK) | INSERT 重複 UK | 業務層分庫分表 (按用戶/區域分片)、應用層樂觀鎖 |
| UPDATE 覆蓋 | 雙邊同時修改同一行 | 行版本號/時間戳樂觀鎖;關鍵數據單邊寫入 |
| DELETE + INSERT | 一方刪除、另一方插入同 PK | 軟刪除 (`is_deleted`)、延遲清理 |
| DDL 不同步 | 單邊 ALTER TABLE | 統一變更流程、雙邊同步執行、pt-online-schema-change |
故障切換與運維
- **寫入流量切換:** 應用層/代理層 (ProxySQL/MaxScale/VIP) 秒級切換寫入目標。
- **斷開同步修復:** `STOP SLAVE` → 修復數據 → `START SLAVE` (GTID 自動定位)。
- **數據一致性校驗:** 定期 `pt-table-checksum` / `pt-table-sync` 檢測修復偏移。
- **監控報警:** `Seconds_Behind_Master > 10`、 `Slave_SQL_Running=No`、 `Executed_Gtid_Set` 停滯。
總結:除非極其必要,優先選「主主只寫一邊」或「單向主從 + ProxySQL 讀寫分離」。真正雙寫雙主是分布式系統最難課題之一 (CAP 權衡)。