基於 Binlog 的非同步複寫是 MySQL 高可用、讀寫分離的基石。本文記錄從原理到生產部署、驗證、在線擴展從庫的全流程。
關鍵檔案:Master binlog、Slave relay-log、master.info (記錄同步位置)、relay-log.info。
[mysqld]
log-bin=mysql-bin # 啟用 Binlog
binlog_format=MIXED # 混合格式 (預設 ROW 更安全)
binlog_cache_size=4M # 事務 Binlog 緩衝
max_binlog_size=300M # 單檔上限
expire_logs_days=3 -- 自動清理天數
server-id=1 # 全域唯一 ID
# 可選:binlog-do-db=db_test # 僅記錄指定庫 (不建議,從庫端過濾更靈活)
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'repl';
FLUSH PRIVILEGES;
# 1. 鎖表備份 (極短暫)
mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS; -- 記錄 File、Position
# 2. 新終端導出資料 (不退出上一會話,否則鎖釋放)
mysqldump -uroot -h127.0.0.1 --single-transaction --master-data=2 --databases db1 > /backup/db1.sql
# 3. 壓縮傳輸到 Slave
tar -czvf db1.tar.gz db1.sql
scp db1.tar.gz root@slave_ip:/backup/
# 4. 解鎖
mysql> UNLOCK TABLES;
[mysqld]
server-id=2 # 唯一,不可與 Master 衝突
relay-log=relay-log
relay-log-index=relay-log.index
read_only=1 # 建議開啟,防止誤寫入
binlog_format=MIXED
binlog_cache_size=4M
max_binlog_size=300M
# log-slave-updates=1 # 若 Slave 也做 Master (鏈式複寫) 需開啟
# 1. 建庫導入
mysql> CREATE DATABASE db1;
mysql> USE db1;
mysql> SET NAMES utf8;
mysql> SOURCE /backup/db1.sql;
# 2. 配置 Master 連線資訊
mysql> CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='repl',
MASTER_PASSWORD='repl',
MASTER_LOG_FILE='mysql-bin.000001', -- 來自 Master SHOW MASTER STATUS
MASTER_LOG_POS=107;
# 3. 啟動並驗證
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G
-- 關鍵指標:
-- Slave_IO_Running: Yes
-- Slave_SQL_Running: Yes
-- Seconds_Behind_Master: 0
| 現象 | 原因 | 解決 |
|---|---|---|
| Slave_IO_Running: Connecting / Last_IO_Errno: 2003 | 防火牆阻擋 3306、網路不通、帳號密碼錯 | 開放埠、檢查 grant host '%'、測試 telnet master 3306 |
| Slave_SQL_Running: No / Last_SQL_Error | 重放 SQL 失敗 (主鍵衝突、表不存在、外鍵錯誤) | 根據錯誤碼修復資料、或跳過錯誤 SET GLOBAL sql_slave_skip_counter=1; START SLAVE; |
| Seconds_Behind_Master 偏大 | 從庫硬體弱、大事務、長 SQL、單線程重放瓶頸 | 升級硬體、啟用並行複寫 (5.6+ slave_parallel_workers)、優化慢 SQL |
原理:利用現有 Slave 完整備份作為新 Slave 基準,避免鎖定 Master。
FLUSH TABLES WITH READ LOCK; SHOW SLAVE STATUS\G 記錄 Relay_Master_Log_File、Exec_Master_Log_Pos (對應 Master 位置)。mysqldump --single-transaction --master-data=2 --all-databases > new_slave.sqlUNLOCK TABLES;CHANGE MASTER TO ... MASTER_LOG_FILE=..., MASTER_LOG_POS=...。START SLAVE; 驗證。理論無上限,實際受限於 Master 網路頻寬、寫入吞吐、Binlog 傳輸能力。官方經驗公式 (假設 90% 讀、10% 寫、讀寫成本比 1:2):
建議:單 Master 掛載 3-5 從庫 為甜蠟點,超過需考慮多級複寫或叢集方案 (Group Replication、InnoDB Cluster)。