MySQL 主主復制(Master-Master Replication)讓兩台伺服器互為主從,任一節點的資料變更都會自動同步至另一節點,實現雙向寫入與高可用。本文提供從環境準備、用戶授權、配置調優、資料初始化、雙向同步啟動到驗證測試的完整落地步驟,並附帶生產級配置範例與關鍵參數解析。
傳統主從僅支援單向同步,從庫不可寫入;主主架構雙節點均可讀寫,適合讀寫分離、負載均衡及災備切換場景。但需妥善處理自增 ID 衝突,通常透過 auto_increment_increment 與 auto_increment_offset 錯開自增步長。
mydb在各節點建立對方專用的 REPLICATION SLAVE 權限帳號,限制來源 IP 提升安全性。
-- Server-1 建立供 Server-2 連線的帳號 GRANT REPLICATION SLAVE ON *.* TO 'server2'@'192.168.0.2' IDENTIFIED BY 'server2'; -- Server-2 建立供 Server-1 連線的帳號 GRANT REPLICATION SLAVE ON *.* TO 'server1'@'192.168.0.1' IDENTIFIED BY 'server1';
my.cnf關鍵參數說明:
server-id:集群內唯一,建議 10/20 區分log-bin:啟用二進制日誌,復制前提replicate-do-db:僅同步指定庫auto_increment_increment=2:自增步長設為節點總數auto_increment_offset:節點 1 為 1,節點 2 為 2,避免主鍵衝突# Server-1 [mysqld] server-id = 10 log-bin = mysql-bin replicate-do-db = mydb auto-increment-increment = 2 auto-increment-offset = 1 # Server-2 [mysqld] server-id = 20 log-bin = mysql-bin replicate-do-db = mydb auto-increment-increment = 2 auto-increment-offset = 2
修改後執行 service mysqld restart 生效。
-- Server-1 執行 FLUSH TABLES WITH READ LOCK; SHOW MASTER STATUS; -- 記錄 File 與 Position,例:mysql-bin.000006, 213 mysqldump --user=root -p mydb > /tmp/mydb.sql UNLOCK TABLES;
-- Server-2 執行 CREATE DATABASE mydb; scp 192.168.0.1:/tmp/mydb.sql ./ mysql -uroot -p mydb < /tmp/mydb.sql LOCK TABLES WITH READ LOCK; SHOW MASTER STATUS; -- 記錄 File 與 Position,例:mysql-bin.000001, 106 UNLOCK TABLES;
-- Server-1 指向 Server-2 CHANGE MASTER TO MASTER_HOST='192.168.0.2', MASTER_USER='server1', MASTER_PASSWORD='server1', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=106; -- Server-2 指向 Server-1 CHANGE MASTER TO MASTER_HOST='192.168.0.1', MASTER_USER='server2', MASTER_PASSWORD='server2', MASTER_LOG_FILE='mysql-bin.000006', MASTER_LOG_POS=213; -- 兩節點均執行 START SLAVE;
任一節點建庫建表,另一節點 SHOW DATABASES 即可見同步結果。
# Master 1 (192.168.0.186) [mysqld] server_id=1 log-bin=/cifpay/mysql-bin.log binlog-ignore-db=mysql auto-increment-increment=2 auto-increment-offset=1 # Master 2 (192.168.0.167) [mysqld] server-id=2 read_only=TRUE binlog-ignore-db=mysql log-bin=/cifpay/mysql-bin.log auto-increment-increment=2 auto-increment-offset=2
重啟後在各節點執行 CHANGE MASTER TO ... 指向對方最新 Binlog 位置,再 START SLAVE。檢查 SHOW SLAVE STATUS\G 確認 Slave_IO_Running: Yes 且 Slave_SQL_Running: Yes。
| 參數 | 作用 | 建議值 |
|---|---|---|
| server-id | 節點唯一標識 | 1~2³²-1 正整數,主從不可重複 |
| log-bin | 啟用二進制日誌 | 必開,否則無法復制 |
| binlog-do-db / binlog-ignore-db | 控制主庫記錄哪些庫 | 按業務精確指定 |
| replicate-do-db / replicate-ignore-db | 控制從庫同步哪些庫 | 與主庫策略對齊 |
| log-slave-updates | 從庫更新是否寫入 Binlog | 鏈式復制時必開 |
| slave-skip-errors | 跳過指定錯誤碼 | 備份庫慎用,讀負載庫可考慮 |
| sync_binlog=1 | 每次提交強制刷盤 | 最高安全,犧牲寫入效能 |
| auto_increment_increment/offset | 主主自增衝突避免 | increment=節點數,offset=1..N |
定期清理避免磁碟耗盡,兩種方式:
PURGE MASTER LOGS TO 'binlog.000002'; 或 PURGE MASTER LOGS BEFORE '2011-05-28 1:35:00'; 或 PURGE MASTER LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY);[mysqld] expire-logs-days = 7 保留 7 天。清理前必須確認所有從庫已讀取目標日誌以降後。
PURGE MASTER LOGS、RESET MASTER、SET SQL_LOG_BIN、SHOW MASTER LOGS/STATUS、SHOW SLAVE HOSTSCHANGE MASTER TO、START/STOP SLAVE、RESET SLAVE、SET GLOBAL SQL_SLAVE_SKIP_COUNTER、SHOW SLAVE STATUS、MASTER_POS_WAIT()單向主從僅提供讀擴展與備份;雙向主主可雙寫負載,但需業務層保證寫入順序安全。生產環境建議搭配 MHA、Orchestrator 或 GTID 增強故障轉移能力。