在部署 MySQL 主從複制之前,首先需要明確雙方的角色與網路配置。本教學採用經典的單主單從架構:
為了安全起見,應建立專門用於複制的帳號,並僅授予必要的 REPLICATION SLAVE 權限:
mysql> GRANT REPLICATION SLAVE ON *.* TO 'rep1'@'192.168.56.2' IDENTIFIED BY '123456'; Query OK, 0 rows affected (0.01 sec)
注意:生產環境建議限制來源 IP,並使用強密碼策略。
編輯 /etc/my.cnf,在 [mysqld] 區段新增:
[mysqld] log-bin=/home/mysql/log/mysql-bin.log server-id=1
修改完成後必須重啟 MySQL 服務生效:
service mysql restart
為確保數據一致性,需在主庫加全局讀鎖:
mysql> FLUSH TABLES WITH READ LOCK; Query OK, 0 rows affected (0.02 sec)
隨後查看當前 Binlog 文件名與位置,此資訊將用於從庫同步起點:
mysql> SHOW MASTER STATUS; +-----------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-----------------+----------+--------------+------------------+-------------------+ | mysqlbin.000021 | 120 | | | | +-----------------+----------+--------------+------------------+-------------------+
在鎖定期間,可透過打包數據目錄方式快速產生快照:
tar -zcvf mysql.tar.gz mysql/ scp mysql.tar.gz root@192.168.56.5:/root
備份完成後釋放鎖定:
mysql> UNLOCK TABLES;
於從庫解壓備份包至對應數據目錄:
tar -zxvf mysql.tar.gz
編輯 my.cnf,設定唯一的 server-id(不可與主庫重複):
[mysqld] server-id=2
使用 --skip-slave-start 參數啟動,避免自動啟動複制進程,便於後續精確配置:
mysqld_safe --skip-slave-start &
在從庫執行 CHANGE MASTER TO,指定主庫連線資訊與同步起點:
mysql> CHANGE MASTER TO
-> MASTER_HOST='192.168.56.2',
-> MASTER_USER='rep1',
-> MASTER_PORT=3306,
-> MASTER_PASSWORD='123456',
-> MASTER_LOG_FILE='mysqlbin.000021',
-> MASTER_LOG_POS=120;
Query OK, 0 rows affected, 2 warnings (0.08 sec)
mysql> START SLAVE; mysql> SHOW SLAVE STATUS\G
成功標準:Slave_IO_Running: Yes 且 Slave_SQL_Running: Yes 均為 Yes。
Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs
原因:直接複製主庫數據目錄導致 auto.cnf 中 UUID 相同。
解決:修改從庫 $datadir/auto.cnf 中的 UUID(16 進制任意變更),重啟 MySQL。
Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'
原因:MASTER_LOG_FILE 參數設定錯誤。
解決:重新執行 CHANGE MASTER TO MASTER_LOG_FILE='正確檔名'; START SLAVE;
在主庫建立測試資料庫與資料表:
CREATE DATABASE zx; USE zx; CREATE TABLE t(id INT); INSERT INTO t VALUES(1),(2),(3);
於從庫查詢驗證同步結果:
SHOW DATABASES; -- 應出現 zx USE zx; SELECT * FROM t; -- 應顯示 1,2,3