| 拓撲 | 寫入節點 | 數據流向 | 一致性 | 可用性 | 典型場景 |
|---|---|---|---|---|---|
| 單向主從 (Master-Slave) | 1 個 Master | Master → Slave (異步) | 最終一致 (有延遲) | Master 掛掉需人工/腳本切主 | 讀寫分離、備份、報表查詢 |
| 雙主 (Master-Master) | 2 個互為主從 | 雙向異步 | 最終一致 (雙向延遲 + 衝突風險) | 雙活寫入、互備 | 雙機房雙活、多寫入入口 |
| 半同步復制 (Semi-sync) | 1 Master + N Slave | Master 等待 ≥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 重放事務
│ (重放/應用) │
└─────────────────┘
[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
CREATE USER 'repl'@'192.168.20.%' IDENTIFIED BY 'StrongReplPass!';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.20.%';
FLUSH PRIVILEGES;
冷備份 (停寫):**
# Master
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS; -- 記錄 File, Position (非 GTID 模式需用)
# 打包數據目錄傳輸到 Slave 解壓
UNLOCK TABLES;
熱備份 (推薦,不停寫): 使用 `mysqldump --single-transaction --master-data=2` 或 `Percona XtraBackup` 物理備份。
[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,...
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;
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 集合>
# 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...
-- 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` | Master | ON | 啟用半同步 |
| `rpl_semi_sync_master_timeout` | Master | 1000-5000 (ms) | 等待 Slave ACK 超時,**超時自動降級為異步** 防止主庫掛起 |
| `rpl_semi_sync_master_wait_no_slave` | Master | ON | 有 Slave 時等待;無 Slave 時不等待 (避免單 Slave 故障阻塞主庫) |
| `rpl_semi_sync_slave_enabled` | Slave | ON | 啟用半同步 |
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 是否處於半同步模式
┌─────────────┐ 半同步復制 ┌─────────────┐
│ 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 的必修功課。