MySQL 主從複製是讀寫分離、災備、數據分發的基石架構。本文基於真實部署日誌(MySQL 5.0.18/5.0.19,Linux),完整記錄配置流程、遇到的經典錯誤(Relay Log 錯誤、Schema 不一致、Binlog 位點偏移)及解決方案,作為生產環境部署參考。
| 角色 | IP | MySQL 版本 | OS |
|---|---|---|---|
| Master | 192.168.100.231 | 5.0.19 | Linux |
| Slave | 192.168.100.234 | 5.0.18 | Linux |
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-do-db = test # 僅同步 test 資料庫(可選,建議生產環境指定)
binlog-format = ROW # 推薦 ROW 格式,減少主從不一致風險
expire-logs-days = 7 # 自動清理 7 天前 Binlog
max-binlog-size = 100M
sync-binlog = 1 # 每次提交刷盤,最高數據安全(性能折中可設 100-1000)
innodb-flush-log-at-trx-commit = 1
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'192.168.100.234' IDENTIFIED BY 'StrongReplPass123!';
FLUSH PRIVILEGES;
systemctl restart mysqld
mysql -e "SHOW MASTER STATUS;"
-- 記錄 File (如 mysql-bin.000001) 和 Position (如 154)
[mysqld]
server-id = 2
relay-log = relay-bin
relay-log-index = relay-bin.index
log-slave-updates = 1 # 若 Slave 需作為其他節點的 Master
read-only = 1 # 防止誤寫入
replicate-do-db = test # 僅同步 test,與 Master binlog-do-db 對應
# replicate-ignore-db = mysql,information_schema,performance_schema
systemctl restart mysqld
mysql -e "
CHANGE MASTER TO
MASTER_HOST = '192.168.100.231',
MASTER_USER = 'repl_user',
MASTER_PASSWORD = 'StrongReplPass123!',
MASTER_LOG_FILE = 'mysql-bin.000001',
MASTER_LOG_POS = 154,
MASTER_CONNECT_RETRY = 10,
MASTER_RETRY_COUNT = 86400;
START SLAVE;
"
mysql -e "SHOW SLAVE STATUS\G"
-- 關鍵指標:
-- Slave_IO_Running: Yes
-- Slave_SQL_Running: Yes
-- Seconds_Behind_Master: 0
-- Last_IO_Error / Last_SQL_Error: 空
現象:Slave_IO_Running=Yes,Slave_SQL_Running=No,錯誤碼 1146。
原因分析:Master 的 Binlog 包含 passport 庫的 DML,但 Slave 未建立該庫,或 replicate-do-db 未包含 passport。日誌顯示 Default database: 'passport',說明 Master 執行時當前庫是 passport。
解決:
CREATE DATABASE passport;replicate-wild-do-table=passport.%(需重啟)操作:直接 scp -r /var/lib/mysql/* slave:/var/lib/mysql/。
後果:Slave 的 auto.cnf (server_uuid) 被覆蓋為 Master 的 UUID,導致主從 UUID 衝突;Relay Log 位點與 Master Binlog 位點不匹配,SQL 線程無法解析。
正確做法:使用 mysqldump + 導入 或 Percona XtraBackup 進行物理備份恢復,保證 UUID 獨立、位點一致。
現象:SQL 線程中斷,錯誤碼 1007。
原因:Master Binlog 開頭包含 CREATE DATABASE test,Slave 因之前手動建庫/拷貝已存在該庫,重放失敗。
解決:
DROP DATABASE test;STOP SLAVE; RESET SLAVE ALL; -- 5.1+ 版本START SLAVE;Master 5.0.19,Slave 5.0.18。雖然通常向下兼容,但建議主從版本保持一致,避免 Binlog 事件解析異常。
# Master 額外優化
binlog-format = ROW
binlog-row-image = MINIMAL # 5.6+ 減少 Binlog 體積
gtid-mode = ON # 5.6+ 啟用 GTID,簡化故障切換
enforce-gtid-consistency = ON
master-info-repository = TABLE # 將主從元數據存表,更可靠
relay-log-info-repository = TABLE
# Slave 額外優化
slave-parallel-workers = 4 # 5.6+ 多線程複製(庫級並行)
slave-parallel-type = LOGICAL_CLOCK # 5.7+ 基於邏輯時鐘並行,無庫限制
slave-preserve-commit-order = 1 # 保證提交順序一致性
relay-log-recovery = ON # 啟動時自動修復損壞 Relay Log
MySQL 主從複製「配置易、調優難、排錯更難」。本文從真實部署日誌提煉出的核心經驗:版本一致、GTID 模式、ROW 格式、專用賬號、嚴格的 replicate-do-db、標準化備份恢復流程、自動化監控告警。避免手動拷貝數據目錄、隨意變更 server-id/UUID、忽略 Binlog 位點管理,是穩定運行的關鍵。建議引入 Orchestrator、MHA、ProxySQL 等中間件構建高可用架構,將人工運維轉為自動化故障切換。