公司所有伺服器遷移至同一機房,開通內網連線。需將多台 Slave 的 Master 連線從公網 IP 切換至內網 IP,**要求業務零感知、資料零丟失**。
MySQL 複寫元資料儲存在 Slave 的 master.info 檔案 (或 `mysql.slave_master_info` 表,MySQL 5.6+)。直接修改此檔案/表中的 `Master_Host` 欄位,配合 `SKIP_SLAVE_START` 啟動,即可無縫切換。
# 1. 停止複寫執行緒
mysql> STOP SLAVE;
# 2. 備份 master.info (舊版檔案式) 或查詢 slave_master_info 表 (新版)
# 檔案式 (MySQL 5.5 及之前)
cp /var/lib/mysql/master.info /var/lib/mysql/master.info.bak.$(date +%F)
# 表式 (MySQL 5.6+)
SELECT * FROM mysql.slave_master_info \G
# 記錄下 Master_Host, Master_User, Master_Port, Master_Log_File, Read_Master_Log_Pos 等關鍵欄位
mysql> CHANGE MASTER TO MASTER_HOST='new_internal_ip';
# 僅修改 Host,其他參數 (User, Password, Log_File, Log_Pos) 保持不變
# 1. 以 --skip-slave-start 啟動 MySQL (防止 Slave 自動啟動)
systemctl stop mysqld
systemctl start mysqld --skip-slave-start
# 或臨時修改 my.cnf: skip_slave_start=1 後重啟
# 2. 登入更新
mysql> UPDATE mysql.slave_master_info SET Master_Host='new_internal_ip' WHERE Master_Host='old_public_ip';
# 3. 重啟 MySQL 移除 skip_slave_start
systemctl restart mysqld
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS \G
確認關鍵輸出:
Master_Host: new_internal_ip
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0
Master_SSL_Allowed: Yes (若原本啟用 SSL)
mysql> STOP SLAVE;
mysql> CHANGE MASTER TO
MASTER_HOST='10.0.1.50',
MASTER_PORT=3306,
MASTER_USER='repl_user_new',
MASTER_PASSWORD='NewStrongPass123!',
MASTER_SSL=1,
MASTER_SSL_CA='/etc/mysql/certs/ca-cert.pem',
MASTER_SSL_CERT='/etc/mysql/certs/client-cert.pem',
MASTER_SSL_KEY='/etc/mysql/certs/client-key.pem';
mysql> START SLAVE;
若啟用 GTID (`gtid_mode=ON`),**不需指定 MASTER_LOG_FILE/POS**,MySQL 會自動基於 GTID 定位:
mysql> CHANGE MASTER TO
MASTER_HOST='new_internal_ip',
MASTER_AUTO_POSITION=1; -- 關鍵:啟用 GTID 自動定位
| 檢查項目 | 命令 | 預期結果 |
|---|---|---|
| IO 執行緒狀態 | SHOW SLAVE STATUS \G | Slave_IO_Running: Yes |
| SQL 執行緒狀態 | SHOW SLAVE STATUS \G | Slave_SQL_Running: Yes |
| 延遲秒數 | Seconds_Behind_Master | 0 或 極小值 |
| 新 Master 連線 | Master_Host | 顯示新內網 IP |
| 錯誤日誌 | tail -f /var/log/mysql/error.log | 無新錯誤 |
| 應用端讀寫 | 業務驗證 | 讀從庫正常、寫主庫正常 |
# 1. 立即停止 Slave
mysql> STOP SLAVE;
# 2. 恢復原 Master Host
mysql> CHANGE MASTER TO MASTER_HOST='old_public_ip';
# 3. 重新啟動
mysql> START SLAVE;
# 4. 驗證恢復正常
mysql> SHOW SLAVE STATUS \G
#!/bin/bash
# 用法: ./change_master_ip.sh [mysql_user] [mysql_pass]
SLAVE_HOST=$1
NEW_MASTER_IP=$2
MYSQL_USER=${3:-root}
MYSQL_PASS=${4:-}
echo "[$(date)] 開始切換 $SLAVE_HOST Master IP 至 $NEW_MASTER_IP"
ssh $SLAVE_HOST "
mysql -u$MYSQL_USER -p$MYSQL_PASS -e \"STOP SLAVE;\"
mysql -u$MYSQL_USER -p$MYSQL_PASS -e \"CHANGE MASTER TO MASTER_HOST='$NEW_MASTER_IP';\"
mysql -u$MYSQL_USER -p$MYSQL_PASS -e \"START SLAVE;\"
sleep 3
mysql -u$MYSQL_USER -p$MYSQL_PASS -e \"SHOW SLAVE STATUS \G\"
"
echo "[$(date)] 切換完成,請人工確認 Slave_IO_Running=Yes, Slave_SQL_Running=Yes"
掌握此流程,即可在機房遷移、雲端上云、災難演練等場景中,安全、快速完成 MySQL 複寫 Master IP 變更,保障資料同步連續性與業務零中斷。