MySQL 3.23+ 引入的基於二進制日志的主從復制,構建高可用架構的基石。本文詳細講解雙節點主從搭建、數據一致性驗證、主庫故障時 PHP 應用層自動切換邏輯。
log-bin 記錄所有變更replicate@10.1.1.2 僅需 FILE 權限 (GRANT FILE ON *.* TO replicate@'10.1.1.2' IDENTIFIED BY 'pass';)
# 1. 啟用 Binlog
[mysqld]
log-bin=master-bin
server-id=1
# 2. 重啟 MySQL 生成 Binlog
service mysql restart
# 3. 獲取一致性快照 (停寫窗口)
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS; -- 記錄 File + Position
# 物理拷貝數據目錄 (或 mysqldump --master-data=2)
UNLOCK TABLES;
# 1. 恢復快照到 Slave 數據目錄,修正權限
chown -R mysql:mysql /var/lib/mysql
chmod 750 /var/lib/mysql
# 2. Slave 配置
[mysqld]
server-id=2
master-host=10.1.1.1
master-user=replicate
master-password=pass
master-port=3306
master-connect-retry=60
replicate-do-db=business_db
# 3. 啟動 Slave 線程
START SLAVE;
# 4. 驗證同步狀態
SHOW SLAVE STATUS \G
# 關鍵指標:Slave_IO_Running=Yes, Slave_SQL_Running=Yes, Seconds_Behind_Master=0
'10.1.1.1', 'user'=>'app', 'pass'=>'xxx', 'db'=>'biz'];
$slave = ['host'=>'10.1.1.2', 'user'=>'app', 'pass'=>'xxx', 'db'=>'biz'];
// 健康檢查:嘗試連接 + 簡單查詢
function check($cfg) {
$link = @mysqli_connect($cfg['host'], $cfg['user'], $cfg['pass'], $cfg['db'], 3306, 2);
if (!$link) return false;
$res = @mysqli_query($link, "SELECT 1");
@mysqli_close($link);
return $res !== false;
}
if ($preferMaster && check($master)) return mysqli_connect(...$master);
if (check($slave)) return mysqli_connect(...$slave);
if (check($master)) return mysqli_connect(...$master); // Slave 掛了回退 Master
throw new Exception("No database available");
}
// 寫操作強制 Master
function writeDb() { return getDbConnection(true); }
// 讀操作優先 Slave
function readDb() { return getDbConnection(false); }
?>
| 指標 | 正常值 | 異常處理 |
|---|---|---|
| Seconds_Behind_Master | 0 (或 <1s) | >10s 告警,檢查網絡/長事務/Slave SQL 線程阻塞 |
| Slave_IO_Running | Yes | No → 檢查網絡連通性、Master Binlog 是否存在、replicate 用戶權限 |
| Slave_SQL_Running | Yes | No → SHOW SLAVE STATUS 看 Last_Error,修復數據衝突後 START SLAVE |
| Relay_Log_Space | 穩定 | 持續增長 → SQL 線程慢於 IO 線程,優化 Slave 查詢/索引 |