Docker 實戰:MySQL 8 全自動 GTID 主從複製架構指南
1. 目標 (Objective)
在傳統部署中,建立 MySQL 複製最煩瑣的莫過於「手動記錄 Binary Log 位點」以及執行繁雜的 CHANGE MASTER TO 指令。本文旨在利用 Docker 容器化 與 GTID (Global Transaction ID) 技術,達成**「自動化握手、狀態自我修復」**的目標,實現一行指令即可啟動具備高可用潛力的資料庫叢集。
2. 技術亮點 (Technical Highlights)
GTID 自動定位:捨棄傳統的
binlog_file與pos,改用全域事務 ID,即使 Replica 容器重啟,也能自動找回斷點續傳。MySQL 8 認證優化:針對
caching_sha2_password引起的連線問題,統一採用mysql_native_password確保複製鏈路的穩定性。Healthcheck 依賴管理:利用 Docker 內建健康檢查,解決 Replica 啟動時 Source 尚未就緒導致的腳本崩潰。
腳本化自動配置:透過
setup.sh自動完成繁瑣的複製命令,達成真正的「開箱即用」。
3. 架構圖描述 (Architecture Diagram)
系統透過 Docker 網路進行通訊,Source 端負責讀寫,Replica 端透過非同步 GTID 請求獲取事務日誌:
[ 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 端核心設定:
[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 的可用性,並在就緒後自動執行同步:
#!/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)
Source 啟動:執行
init.sql建立repl帳號並分配REPLICATION SLAVE權限。健康檢查 (Healthcheck):Docker 定期對 Source 執行
mysqladmin ping。Replica 啟動:偵測到 Source 為
healthy狀態後啟動容器。自動握手:Replica 執行
setup.sh,將SOURCE_AUTO_POSITION設為 1,開始接收 GTID 日誌。
6. 編排中心 (docker-compose.yml)
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 時,表示架構已完美運行:
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 的緊密配合,我們不僅縮短了災難復原的時間,更為日後的「一主多從」擴展打下了自動化的基礎。
沒有留言:
張貼留言