2025年12月27日 星期六

Docker 實戰:MySQL 8 全自動 GTID 主從複製架構指南

Docker 實戰:MySQL 8 全自動 GTID 主從複製架構指南

1. 目標 (Objective)

在傳統部署中,建立 MySQL 複製最煩瑣的莫過於「手動記錄 Binary Log 位點」以及執行繁雜的 CHANGE MASTER TO 指令。本文旨在利用 Docker 容器化GTID (Global Transaction ID) 技術,達成**「自動化握手、狀態自我修復」**的目標,實現一行指令即可啟動具備高可用潛力的資料庫叢集。


2. 技術亮點 (Technical Highlights)

  • GTID 自動定位:捨棄傳統的 binlog_filepos,改用全域事務 ID,即使 Replica 容器重啟,也能自動找回斷點續傳。

  • MySQL 8 認證優化:針對 caching_sha2_password 引起的連線問題,統一採用 mysql_native_password 確保複製鏈路的穩定性。

  • Healthcheck 依賴管理:利用 Docker 內建健康檢查,解決 Replica 啟動時 Source 尚未就緒導致的腳本崩潰。

  • 腳本化自動配置:透過 setup.sh 自動完成繁瑣的複製命令,達成真正的「開箱即用」。


3. 架構圖描述 (Architecture Diagram)

系統透過 Docker 網路進行通訊,Source 端負責讀寫,Replica 端透過非同步 GTID 請求獲取事務日誌:

Plaintext
[ Client (Write) ]        [ Client (Read Only) ]
       │                         │
       ▼                         ▼
[ MySQL Source ]  ── (Async) ──▶ [ MySQL Replica ]
 (Server-ID: 1)             (Server-ID: 2 / Read Only)
       │                         │
 [ Binary Log ]           [ Relay Log & SQL Thread ]

4. 實戰配置精要

A. GTID 關鍵配置 (my.cnf)

在 MySQL 8 中,啟用 GTID 需要嚴格的一致性檢查。

Source 端核心設定:

Ini, TOML
[mysqld]
server-id=1
log_bin=mysql-bin
binlog_format=ROW
gtid_mode=ON
enforce_gtid_consistency=ON
# MySQL 8 安全認證相容性
default-authentication-plugin=mysql_native_password
skip-host-cache
skip-name-resolve

B. 自動化握手腳本 (replica/setup.sh)

這是解決「手動操作」的靈魂腳本。它會持續檢測 Source 的可用性,並在就緒後自動執行同步:

Bash
#!/bin/bash
set -e

echo "等待 Source MySQL 服務就緒..."
until mysql -h mysql-source -urepl -preplpass -e "SELECT 1;" &> /dev/null; do
  sleep 2
done

echo "檢測到 Source 已上線,開始配置 GTID 同步..."
mysql -uroot -prootpassword <<EOSQL
STOP REPLICA;
CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='mysql-source',
  SOURCE_USER='repl',
  SOURCE_PASSWORD='replpass',
  SOURCE_AUTO_POSITION=1;
START REPLICA;
EOSQL
echo "MySQL 複製鏈路已建立!"

5. 流程圖描述 (Flowchart)

  1. Source 啟動:執行 init.sql 建立 repl 帳號並分配 REPLICATION SLAVE 權限。

  2. 健康檢查 (Healthcheck):Docker 定期對 Source 執行 mysqladmin ping

  3. Replica 啟動:偵測到 Source 為 healthy 狀態後啟動容器。

  4. 自動握手:Replica 執行 setup.sh,將 SOURCE_AUTO_POSITION 設為 1,開始接收 GTID 日誌。


6. 編排中心 (docker-compose.yml)

YAML
services:
  mysql-source:
    image: mysql:8.0
    container_name: mysql-source
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
    volumes:
      - ./source/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./source/init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-uroot", "-prootpassword"]
      interval: 5s
      retries: 5

  mysql-replica:
    image: mysql:8.0
    container_name: mysql-replica
    depends_on:
      mysql-source:
        condition: service_healthy
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
    volumes:
      - ./replica/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./replica/setup.sh:/docker-entrypoint-initdb.d/setup.sh

7. 驗證與排錯 (Troubleshooting)

同步檢查

執行以下指令確認狀態,當看到兩個 Yes 時,表示架構已完美運行:

Bash
docker exec -it mysql-replica mysql -uroot -prootpassword -e "SHOW REPLICA STATUS\G"
  • Replica_IO_Running: Yes (負責讀取 Source 的 Binlog)

  • Replica_SQL_Running: Yes (負責在 Replica 執行事務)

常見陷阱

  • 權限問題:MySQL 8 的設定檔目錄具備權限檢查,請確保宿主機執行 chmod 644 ./source/my.cnf,否則設定會被忽略。

  • 認證失敗:若出現 caching_sha2_password 錯誤,請檢查 init.sql 是否確實使用了 IDENTIFIED WITH mysql_native_password 建立帳號。


8. 結論 (Conclusion)

這套架構的核心價值在於**「環境與配置的程式碼化」**。透過 GTID 與 Docker 的緊密配合,我們不僅縮短了災難復原的時間,更為日後的「一主多從」擴展打下了自動化的基礎。

沒有留言:

張貼留言

AI 浪潮下的軟體業轉型:從「程式碼產出」到「價值驗證」的權力移轉

  前言:消失的「碼農」,崛起的「編排者」 過去兩年,媒體熱衷於討論 AI 是否會取代體力勞動者。然而,身處風暴中心的軟體從業人員心知肚明: 衝擊最深、速度最快的,其實是軟體產業。 AI 改變的不只是 IDE 裡的自動補全,它正在重塑軟體生產的「價值公式」。我們必須認清一個現實...