首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 主從、主主復制與半同步復制架構全解析:從原理到生產落地

     編輯:MySQL 綜合教學

核心復制拓撲對比

拓撲寫入節點數據流向一致性可用性典型場景
單向主從 (Master-Slave)1 個 MasterMaster → Slave (異步)最終一致 (有延遲)Master 掛掉需人工/腳本切主讀寫分離、備份、報表查詢
雙主 (Master-Master)2 個互為主從雙向異步最終一致 (雙向延遲 + 衝突風險)雙活寫入、互備雙機房雙活、多寫入入口
半同步復制 (Semi-sync)1 Master + N SlaveMaster 等待 ≥1 Slave 收到 Binlog 才提交**準同步** (數據不丟失,但有極小窗口可讀舊數據)Master 掛掉數據零丟失,Slave 可快速升主金融核心、強一致性要求業務
GTID + 多源復制 (5.6+/8.0)多 Master → 1 Slave基於事務 ID (GTID) 自動定位最終一致自動故障轉移友好分庫匯總、多租戶聚合

異步復制核心原理 (三線程模型)

Master (1 線程)          Slave (2 線程)
┌─────────────────┐      ┌─────────────────┐
│ Binlog Dump Thr │─────▶│   I/O Thread    │ → 讀取 Binlog 寫入 Relay Log
│ (發送 Binlog)   │      │ (接收/寫 Relay) │
└─────────────────┘      └────────┬────────┘
                                   │
                                   ▼
                          ┌─────────────────┐
                          │   SQL Thread    │ → 解析 Relay Log 重放事務
                          │ (重放/應用)     │
                          └─────────────────┘
  • Binlog 格式: `ROW` (行級,最安全、數據量大) / `STATEMENT` (語句級,舊版默認) / `MIXED` (混合,推薦)。
  • Relay Log: Slave 本地緩存的 Binlog 副本,格式同 Binlog,`SQL Thread` 回放後自動清理。
  • 關鍵狀態文件: `master.info` (記錄 Master 連接信息、Binlog 讀取位置)、`relay-log.info` (記錄 Relay Log 執行位置)。

單向主從搭建標準流程 (GTID 模式推薦 5.6+)

1. Master 配置 (`my.cnf`)


[mysqld]
server-id = 1                          # 全局唯一
log-bin = mysql-bin                    # 啟用 Binlog
binlog-format = ROW                    # 行級格式
gtid_mode = ON                         # 啟用 GTID
enforce-gtid-consistency = ON          # 強制 GTID 一致性
binlog-do-db = biz_db                  # 只同步指定庫 (可選)
binlog-ignore-db = mysql,sys,performance_schema,information_schema
sync_binlog = 1                        # 每事務刷盤,最安全
innodb_flush_log_at_trx_commit = 1

2. 創建復制賬號


CREATE USER 'repl'@'192.168.20.%' IDENTIFIED BY 'StrongReplPass!';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.20.%';
FLUSH PRIVILEGES;

3. 基線數據同步 (冷備份法 / 熱備份法)

冷備份 (停寫):**


# Master
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;  -- 記錄 File, Position (非 GTID 模式需用)
# 打包數據目錄傳輸到 Slave 解壓
UNLOCK TABLES;

熱備份 (推薦,不停寫): 使用 `mysqldump --single-transaction --master-data=2` 或 `Percona XtraBackup` 物理備份。

4. Slave 配置 (`my.cnf`)


[mysqld]
server-id = 2                          # 唯一,≠ Master
relay-log = relay-bin                  # 獨立 Relay Log 文件名
log-slave-updates = ON                 # **關鍵**:Slave 重放後寫入自身 Binlog,支撐級聯/雙主
gtid_mode = ON
enforce-gtid-consistency = ON
replicate-do-db = biz_db               # 只同步指定庫 (從庫過濾)
replicate-ignore-db = mysql,sys,...

5. 建立復制鏈接 (GTID 模式無需手動指定 File/Position)


CHANGE MASTER TO
  MASTER_HOST='192.168.20.101',
  MASTER_USER='repl',
  MASTER_PASSWORD='StrongReplPass!',
  MASTER_PORT=3306,
  MASTER_AUTO_POSITION=1;   -- GTID 模式核心:自動定位
START SLAVE;

6. 驗證


SHOW SLAVE STATUS\G
-- 關鍵指標:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0  -- 延遲秒數
Master_UUID: 
Retrieved_Gtid_Set: <已接收 GTID 集合>
Executed_Gtid_Set: <已執行 GTID 集合>

雙主 (主主) 搭建關鍵點

  1. 雙向各自配置 `server-id`、啟用 `log-bin`、`log-slave-updates`;
  2. 互為 Master/Slave,創建對端復制賬號;
  3. 自增衝突預防 (核心):
    
        # Master A (server-id=1)
        auto_increment_offset = 1
        auto_increment_increment = 2  -- 生成 1,3,5,7...
        
        # Master B (server-id=2)
        auto_increment_offset = 2
        auto_increment_increment = 2  -- 生成 2,4,6,8...
        
  4. 雙向 `CHANGE MASTER TO ... MASTER_AUTO_POSITION=1; START SLAVE;`;
  5. 驗證雙向 `Seconds_Behind_Master` 均為 0;
  6. **寫入路由策略**:應用層分流 (按用戶/業務分片寫入不同 Master) 或中間件 (ProxySQL) 路由,**嚴禁雙寫同一表** 避免衝突。

MySQL 5.5+ 半同步復制 部署與調優

插件安裝 (動態加載)


-- Master
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
-- Slave
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

-- 驗證
SHOW GLOBAL VARIABLES LIKE 'rpl_semi_sync%';

核心參數配置

參數角色推薦值說明
`rpl_semi_sync_master_enabled`MasterON啟用半同步
`rpl_semi_sync_master_timeout`Master1000-5000 (ms)等待 Slave ACK 超時,**超時自動降級為異步** 防止主庫掛起
`rpl_semi_sync_master_wait_no_slave`MasterON有 Slave 時等待;無 Slave 時不等待 (避免單 Slave 故障阻塞主庫)
`rpl_semi_sync_slave_enabled`SlaveON啟用半同步

啟用流程 (平滑切換)

  1. 先建立正常異步復制,確保 `Seconds_Behind_Master=0` (追平);
  2. `STOP SLAVE;` (Slave);
  3. Master: `SET GLOBAL rpl_semi_sync_master_enabled=1; SET GLOBAL rpl_semi_sync_master_timeout=2000;`;
  4. Slave: `SET GLOBAL rpl_semi_sync_slave_enabled=1;`;
  5. `START SLAVE;` (Slave);
  6. 驗證:`SHOW GLOBAL STATUS LIKE 'Rpl_semi_sync%';` 關注 `Rpl_semi_sync_master_status=ON`、`Rpl_semi_sync_slave_status=ON`、`Rpl_semi_sync_master_yes_tx` 遞增。

關鍵狀態監控指標


SHOW GLOBAL STATUS LIKE 'Rpl_semi_sync%';
-- 重點:
Rpl_semi_sync_master_status: ON              -- Master 是否處於半同步模式
Rpl_semi_sync_master_yes_tx: 12345           -- 成功收到 Slave ACK 的事務數
Rpl_semi_sync_master_no_tx: 3                -- 超時降級異步提交的事務數 (應極低)
Rpl_semi_sync_master_net_avg_wait_time: 2.3  -- 平均網絡等待時間 (ms)
Rpl_semi_sync_slave_status: ON               -- Slave 是否處於半同步模式

生產級高可用架構建議 (MHA / Orchestrator / GTID + ProxySQL)

┌─────────────┐     半同步復制      ┌─────────────┐
│  Master A   │ ◀─────────────────▶ │  Slave B    │  (同機房/同可用區,超低延遲)
│  (Primary)  │   同步 Binlog 確認  │  (Standby)  │
└──────┬──────┘                     └──────┬──────┘
       │                                   │
       │ 異步復制 (跨區容災)                │ 異步復制
       ▼                                   ▼
┌─────────────┐                     ┌─────────────┐
│  Slave C    │                     │  Slave D    │
│ (異地只讀)  │                     │ (異地備份)  │
└─────────────┘                     └─────────────┘

故障轉移:Orchestrator 監控 → 檢測 Master 故障 → 自動提升 Slave B (半同步保證數據零丟失) → ProxySQL 切換寫入路由 → 應用無感遷移

結語

MySQL 復制體系從異步主從、雙主到半同步,核心權衡在於 **性能 (異步無等待) vs 數據安全 (半同步確認) vs 可用性 (自動故障轉移)**。生產建議:**核心業務採用半同步雙節點 (同城雙活) + 異地異步只讀/備份節點**,配合 **GTID 模式簡化拓撲管理**,**Orchestrator/MHA 實現秒級自動故障轉移**,**ProxySQL 實現讀寫分離與流控**。定期演練 `SHOW SLAVE STATUS` 關鍵指標解讀與故障切換流程,是 DBA 的必修功課。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved