MySQL/複製
複製意味著寫入主 MySQL 伺服器的資料將被髮送到單獨的伺服器並在那裡執行。
應用
- 備份
- 將讀取訪問分散到多個伺服器以實現可擴充套件性
- 故障轉移/高可用性
複製型別
- 非同步複製(基本主從)
- 半非同步複製(非同步複製 + 強制在完成查詢之前進行 1 次從伺服器複製)
複製配置
- 標準:主->從
- 雙主:主<->主
在主主複製中,兩個主機同時是主伺服器和從伺服器。 伺服器 A 複製到伺服器 B,伺服器 B 複製到伺服器 A。 沒有一致性檢查,即使配置了 auto_increment_increment/auto_increment_offset,也不應將兩個伺服器用於併發寫入。
這是最簡單的複製。 主伺服器寫入二進位制日誌檔案,從伺服器可以讀取此日誌檔案(可能選擇性地讀取)以重放查詢語句。 它是非同步的,這意味著主伺服器和從伺服器在特定時間點可能具有不同的狀態; 此外,此設定可以承受網路斷開連線。
在 /etc/mysql/my.cnf 中,在 [mysqld] 部分
- 定義伺服器識別符號(檢測迴圈?); 通常我們會使用
1表示伺服器,但它可以是不同的
server-id = 1
- 複製基於 二進位制日誌,因此請啟用它們
log-bin # or log-bin = /var/log/mysql/mysql-bin.log
為從伺服器建立一個新使用者以連線
CREATE USER 'myreplication';
SET PASSWORD FOR 'myreplication' = PASSWORD('mypass');
GRANT REPLICATION SLAVE ON *.* to 'myreplication';
驗證您的伺服器識別符號
SHOW VARIABLES LIKE 'server_id';
在 /etc/mysql/my.cnf 中,在 [mysqld] 部分
- 定義伺服器識別符號,與主伺服器不同(以及與其他從伺服器不同)
server-id = 2
- 使用以下命令驗證
SHOW VARIABLES LIKE 'server_id';
- 您還可以將從伺服器主機名宣告給主伺服器(參見下面的
SHOW SLAVE HOSTS)
report-host=slave1
宣告主伺服器
CHANGE MASTER TO MASTER_HOST='master_addr', MASTER_USER='myreplication', MASTER_PASSWORD='mypass';
如果從備份設定複製,請指定起點(新增到前面的命令中)
MASTER_LOG_FILE='<binary_log_from_master>', MASTER_LOG_POS=<master_binary_log_position>;
啟動複製
START SLAVE;
這將在您的資料目錄中建立一個名為 master.info 的檔案,通常為 /var/lib/mysql/master.info; 此檔案將包含從伺服器配置和狀態。
待辦事項
Oct 15 21:11:19 builder mysqld[4266]: 101015 21:11:19 [Warning] Neither --relay-log nor --relay-log-index were used; so replication may break when this MySQL server acts as a slave and has his hostname changed!! Please use '--relay-log=mysqld-relay-bin' to avoid this problem.
在從伺服器上,鍵入
SHOW SLAVE STATUS;
或更多,以獲得更易讀(基於行的)輸出
SHOW SLAVE STATUS\G
示例
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: master_addr
Master_User: myreplication
Master_Port: 3306
...
特別檢查
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
您可以檢查複製的非同步性質
Seconds_Behind_Master: 0
另請參閱
mysql> SHOW GLOBAL VARIABLES LIKE "%SLAVE%";
您可以在程序列表中看到來自從伺服器的連線。
mysql> SHOW PROCESSLIST\G
[...]
*************************** 6. row ***************************
Id: 14485
User: myreplication
Host: 10.1.0.106:33744
db: NULL
Command: Binlog Dump
Time: 31272
State: Has sent all binlog to slave; waiting for binlog to be updated
Info: NULL
如果您啟用了 report-host,從伺服器也可見於
mysql> SHOW SLAVE HOSTS; +-----------+---------+------+-------------------+-----------+ | Server_id | Host | Port | Rpl_recovery_rank | Master_id | +-----------+---------+------+-------------------+-----------+ | 2 | myslave | 3306 | 0 | 1 | +-----------+---------+------+-------------------+-----------+ 1 row in set (0.00 sec)
請注意,這種複製是一種簡單的重放,類似於將 mysqldump 輸出饋送到 mysql 客戶端。 因此,要保持一致性
- 避免在從伺服器上寫入關鍵資料
- 在主伺服器和從伺服器上都使用相同的資料啟動複製
- 要測試:我們懷疑最好在主伺服器和從伺服器上使用相同版本的 MySQL
預設情況下,複製將在遇到錯誤時停止。 如果您的主伺服器和從伺服器在開始時不一致,或者由於網路錯誤導致查詢格式錯誤,則可能會發生這種情況。
在這種情況下,您將在系統日誌(通常為 /var/log/syslog)中獲得跟蹤
Oct 15 21:11:19 builder mysqld[4266]: 101015 21:11:19 [ERROR] Slave: Error 'Table 'mybase.form'
doesn't exist' on query. Default database: 'mybase'. Query:
'INSERT INTO `form` (`form_id`,`timestamp`,`user_id`) VALUES ('abed',1287172429,0)',
Error_code: 1146
最好的方法是完全重置複製。
您也可以手動修復錯誤,然後要求 MySQL 以這種方式跳過 1 條語句
STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; START SLAVE;
您可以將 SQL_SLAVE_SKIP_COUNTER 設定為任何數字,例如 100。 請注意,在這種情況下,它將跳過有效語句和無效語句,而不僅僅是錯誤。
另一種修復損壞複製的方法是使用 Maatkit 工具。
- mk-slave-restart(如果存在更多錯誤,並且
SQL_SLAVE_SKIP_COUNTER無濟於事,則重新啟動從伺服器上的複製) - mk-table-checksum(在主伺服器和從伺服器上執行表的校驗和)
- mk-table-sync(根據 mk-table-checksum 生成的統計資訊,將從伺服器與主伺服器同步)
要擦除複製
- 鍵入
mysql> RESET SLAVE;
- 注意:此時,MySQL 暫停了從伺服器並使用預設值替換了配置。
master.info檔案也被刪除。 - 重新啟動 MySQL 以清除所有配置。
警告:STOP SLAVE 將停止複製。 它可以手動重新啟動,或者(預設情況下)如果您重新啟動 MySQL 伺服器,它將自動恢復。 為了在啟動過程中避免複製的自動啟動,請在您的配置檔案中新增
slave-skip-start
如果您想永久停止複製(並將伺服器用於其他目的),則需要如上所述重置配置。
此時,您的從伺服器配置應該完全為空
mysql> SHOW SLAVE STATUS; Empty set (0.00 sec)
一些提示可以放在每個有關複製的請求之前的註釋中。 例如透過 PHP Mysqlnd 外掛(用於本機驅動程式)。[1]
- MYSQLND_MS_MASTER_SWITCH:強制在主伺服器上執行請求。
- MYSQLND_MS_SLAVE_SWITCH:強制在從伺服器上執行請求。
- MYSQLND_MS_LAST_USED_SWITCH:強制在最後使用的伺服器上執行請求。
作為複製和叢集的替代方案,MySQL Federated 儲存引擎允許您在伺服器上建立一個表,該表與另一個伺服器上的相同表同步。