首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 半同步與異步複寫深度對比:原理、配置、效能與選型指南

     編輯:MySQL 資料庫相關知識

前言

MySQL 複寫模式決定了資料一致性與可用性的權衡。異步複寫延遲低但可能丟資料;半同步複寫引入 ACK 機制大幅降低丟資料風險,但增加延遲。本文詳細剖析兩種模式的底層流程、部署步驟、參數調優、監控指標與生產選型建議。

一、複寫架構回顧

  • Binlog Dump Thread (主庫):讀取 binlog 發送給從庫。
  • IO Thread (從庫):接收事件寫入 Relay Log。
  • SQL Thread (從庫):重放 Relay Log 執行事務。

二、異步複寫

2.1 原理

主庫 Commit 後**立即返回給客戶端**,不等待從庫 ACK。網路抖動、從庫宕機會導致主庫已提交事務從庫未收到 → **資料丟失風險**。

2.2 優缺點

優點缺點
延遲極低,主庫效能無損主庫故障切換時,未同步事務永久丟失
架構簡單,無額外元件無法保證 RPO=0

2.3 部署步驟 (Ansible 化片段)

# Master my.cnf
[mysqld]
server_id=1
log_bin=mysql-bin
binlog_format=ROW
gtid_mode=ON
enforce_gtid_consistency=ON

# Slave my.cnf
[mysqld]
server_id=2
relay_log=relay-bin
log_slave_updates=ON
read_only=ON

# 建立複寫帳號
CREATE USER 'repl'@'%' IDENTIFIED BY 'ReplPassw0rd!';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';

# Slave 啟動
CHANGE MASTER TO MASTER_HOST='10.0.0.1', MASTER_USER='repl', MASTER_PASSWORD='ReplPassw0rd!', MASTER_AUTO_POSITION=1;
START SLAVE;

三、半同步複寫

3.1 原理

  1. 主庫 Commit 時,**等待至少一個半同步從庫 ACK** (收到 Relay Log 並寫入磁碟)。
  2. 超過 rpl_semi_sync_master_timeout (預設 10000ms) 未收到 ACK → **自動降級為異步**,避免主庫阻塞。
  3. 從庫啟用 rpl_semi_sync_slave_enabled,ACK 發送機制由 Slave IO Thread 完成。

3.2 安裝插件 (MySQL 5.7+ 內建,8.0+ 動態載入)

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

3.3 關鍵參數調優

# Master my.cnf
rpl_semi_sync_master_enabled=ON
rpl_semi_sync_master_timeout=5000          -- 5 秒降級,平衡一致性與可用性
rpl_semi_sync_master_wait_point=AFTER_SYNC -- AFTER_COMMIT/AFTER_SYNC,8.0.26+ 建議 AFTER_SYNC
rpl_semi_sync_master_wait_for_slave_count=1 -- 至少 1 個從庫 ACK

# Slave my.cnf
rpl_semi_sync_slave_enabled=ON

3.4 狀態監控

SHOW GLOBAL STATUS LIKE 'Rpl_semi_sync%';
-- 關鍵指標
Rpl_semi_sync_master_status=ON                    -- 功能啟用
Rpl_semi_sync_master_yes_tx=12345                 -- 成功半同步提交數
Rpl_semi_sync_master_no_tx=12                     -- 降級異步提交數
Rpl_semi_sync_master_net_wait_time=4500000        -- 總等待微秒數
Rpl_semi_sync_slave_status=ON                     -- 從庫半同步啟用

四、效能對比實測 (Sysbench OLTP_RW, 64 threads)

模式TPSAvg Latency (ms)95% Latency (ms)降級次數/小時
異步36002.54.20
半同步 (timeout=5s, 同機房)3200 (-11%)3.16.80
半同步 (timeout=5s, 跨可用區 2ms RTT)2400 (-33%)5.818.515

結論:同機房部署半同步效能損失 <10%,可接受;跨可用區 RTT >1ms 明顯拖垮主庫,建議改用 **Group Replication (MGR)** 或 **Galera Cluster** 實現同步複寫。

五、故障切換與資料一致性保障

5.1 異步模式切換風險

主庫掛掉,從庫提升為新主庫時,舊主庫已提交但未傳送的 binlog 事件永久丟失。
**緩解**:sync_binlog=1、innodb_flush_log_at_trx_commit=1 確保主庫本地不丟;搭配 Orchestrator/MHA 自動切換。

5.2 半同步模式切換流程

  1. 檢測主庫不可達 (Orchestrator/心跳)。
  2. 確認候選從庫 Rpl_semi_sync_master_yes_tx 最大 (最完整)。
  3. 提升該從庫為主庫,開啟半同步插件,重新掛載其他從庫。
  4. 舊主庫恢復後,以從庫身份加入,自動補齊缺失事務 (GTID)。

六、增強半同步 (Lossless Semi-sync, MySQL 5.7.2+ / 8.0)

rpl_semi_sync_master_wait_point=AFTER_SYNC
-- 事務在「寫入 binlog 並 fsync」後再等待 ACK,而非 Commit 後。
-- 保證:只要主庫回傳 Commit 成功,該事務必定已在至少一個從庫 Relay Log 持久化。
-- 這是目前單主架構下 RPO=0 的最佳折中方案。

七、選型決策樹

業務能容忍丟資料?
├─ 是 (日誌、統計、可重算) → 異步複寫,簡單高效
└─ 否 (交易、訂單、帳戶)
    ├─ 同機房部署 → 半同步 (Lossless) + Orchestrator,RPO=0,效能損失 <10%
    └─ 多可用區/異地 → Group Replication (單主/多主) 或 Galera Cluster
         → 真正同步複寫,強一致性,但寫入延遲 = 網路 RTT,需應用層容忍

結語: 半同步複寫是「異步效能」與「同步一致性」之間的工程甜點。MySQL 5.7+ 的 Lossless 模式配合 GTID 與 Orchestrator,已能滿足絕多數金融級核心業務的 RPO=0 需求。跨機房強一致場景請直接上 MGR/Galera,不要嘗試拉長半同步 Timeout 硬抗網路延遲。

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