MySQL 的主從複製是基於二進制日誌(Binary Log,簡稱 Binlog)實現的高可用架構核心。整個複製過程涉及三個關鍵線程協同工作:主庫的 Binlog Dump 線程、從庫的 I/O 線程以及 SQL 線程。

MySQL 4.0 之前僅採用雙線程模型(主從各一),從庫單線程同時負責接收和重放,易導致重放緩慢時阻塞接收。引入 Relay Log 後,接收與重放解耦,顯著提升穩定性與性能。
[mysqld] log-bin=mysql-bin server-id=1
關鍵點:server-id 必須全局唯一(範圍 1~232-1)。若設為 0 或未顯式配置,MySQL 會自動改為 1,但未顯式配置時從庫 IO 線程會報錯 Misconfigured master - server_id was not set。
[mysqld] server-id=2
從庫可選擇不開啟 Binlog;若開啟並需記錄重放事件,需設定 log_slave_updates=1。配置完成後重啟雙方服務。
mysql> CREATE USER 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass'; mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%.mydomain.com';
使用 mysqldump 產生帶位置信息的備份:
# mysqldump --master-data=2 -R --single-transaction -A > 3306_20160815.sql
備份文件頭部包含關鍵同步座標:
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000016', MASTER_LOG_POS=120;
# mysql < 3306_20160815.sql
mysql> CHANGE MASTER TO
MASTER_HOST='master_host',
MASTER_USER='replication_user',
MASTER_PASSWORD='replication_pass',
MASTER_LOG_FILE='mysql-bin.000016',
MASTER_LOG_POS=120;
執行後信息寫入 master.info 和 relay-log.info,並未立即連接。隨後啟動:
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G
核心指標均為 Yes 即成功:
Slave_IO_Running: Yes Slave_SQL_Running: Yes
記錄原始 SQL 語句。MySQL 3.23 即引入。
UUID()、NOW() 等非確定性函數導致主從不一致;LIMIT 無 ORDER BY 時結果不可預測;INSERT ... SELECT 需更多行鎖;UDF 必須確保確定性。MySQL 5.1 引入,記錄行級變更。
INSERT ... SELECT、自增列、無索引 UPDATE/DELETE 鎖更少。動態切換 SBR/RBR。MySQL 5.7.7 前默認 SBR,之後默認 RBR。遇 unsafe statements 自動切換 RBR。切換條件參考官方文檔。
存儲從庫 I/O 線程接收的 Binlog 事件,格式同 Binlog,可用 mysqlbinlog 解析。參數 relay_log、relay_log_index 控制文件名。切換場景:Slave IO 線程啟動、FLUSH LOGS、達到 max_relay_log_size(默認 0,沿用 max_binlog_size)。SQL 線程重放完畢自動清理(受 relay_log_purge 控制)。
記錄主庫連接信息(主機、端口、用戶、密碼)及從庫已讀取的 Binlog 位置(對應 Master_Log_File、Read_Master_Log_Pos)。
記錄 SQL 線程重放進度(對應 Relay_Master_Log_File、Exec_Master_Log_Pos),確保重啟後斷點續傳。
傳統模式下,master.info/relay-log.info 異步刷盤,OS 崩潰導致內存數據丟失,重啟後重複執行。MySQL 5.6 引入兩參數解決:
master_info_repository=TABLE:信息存入 mysql.slave_master_info 表relay_log_info_repository=TABLE:信息存入 mysql.slave_relay_log_info 表雙參數設為 TABLE 後,相關操作納入事務,實現崩潰安全。
fsync 系統調用。master_delay 參數控制)。