7×24 小時音視頻直播業務,要求數據庫單點故障秒級切換,查詢零中斷。採用 **MySQL 內建異步復制** 構建雙主互備,配合 PHP 連接層故障轉移。
-- 1. 創建復制賬號(僅需 FILE 權限)
GRANT FILE ON *.* TO 'repl'@'10.1.1.2' IDENTIFIED BY 'repl_pass';
FLUSH PRIVILEGES;
-- 2. 開啟 Binlog
# my.cnf [mysqld]
log-bin=mysql-bin
server-id=1
-- 3. 獲取一致性快照
FLUSH TABLES WITH READ LOCK;
-- 記錄 SHOW MASTER STATUS 輸出的 File/Position
-- 物理拷貝數據目錄或 mysqldump --single-transaction --master-data=2
UNLOCK TABLES;
-- 1. 恢復快照數據,設置 server-id=2
-- 2. 配置復制源
CHANGE MASTER TO
MASTER_HOST='10.1.1.1',
MASTER_USER='repl',
MASTER_PASSWORD='repl_pass',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=107;
-- 3. 啟動復制
START SLAVE;
SHOW SLAVE STATUS\G -- 確認 Slave_IO_Running=Yes, Slave_SQL_Running=Yes
-- 在 B 上開啟 Binlog (server-id=2)
-- 在 B 創建反向復制賬號
GRANT FILE ON *.* TO 'repl'@'10.1.1.1' IDENTIFIED BY 'repl_pass';
-- 在 A 配置反向復制
CHANGE MASTER TO
MASTER_HOST='10.1.1.2',
MASTER_USER='repl',
MASTER_PASSWORD='repl_pass',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=...;
START SLAVE;
function db_connect_plus() {
$username = 'app_user';
$password = 'apppass';
$primary = '10.1.1.1';
$backup = '10.1.1.2';
$timeout = 3; // 秒,關鍵:避免整機掛掉時長時間阻塞
// 嘗試主庫:先 TCP 探活,再真連接
if ($fp = @fsockopen($primary, 3306, $errno, $errstr, $timeout)) {
fclose($fp);
return mysql_connect($primary, $username, $password);
}
// 主庫不可達,切換備庫
if ($fp = @fsockopen($backup, 3306, $errno, $errstr, $timeout)) {
fclose($fp);
return mysql_connect($backup, $username, $password);
}
return false; // 雙雙不可用
}
關鍵點: fsockopen 提供可控超時,解決 mysql_connect 無超時參數導致掛起問題。
FLUSH TABLES WITH READ LOCK 狀態下獲取 Binlog 位點並備份,否則主從位點偏移導致主鍵衝突報錯。auto_increment_offset/step 錯開自增 ID。Seconds_Behind_Master 持續 > 0 需報警,排查長事務/大查詢/從庫硬件瓶頸。START SLAVE。MySQL 內建復制配置簡單、成本低,配合應用層 TCP 探活切換,可構建高可用架構。核心在於:**一致性快照獲取、雙向復制拓撲、應用層超時切換、寫入單點化避免衝突、持續監控延遲**。