mysql 主從複製(replication) 同步速度快,簡單易用,並且相當可靠。
不過,當你檢查到主從數據不一致的時候,很難判斷出問題所在(軟件問題?硬件問題?網絡傳輸問題?)
一個比較常見的情況是軟硬件或者網絡傳輸出錯,導致主服務器上運行的sql語句與從服務器上運行的sql語句不一致(稱爲event corrupt)。
爲了解決這個問題, mysql的開發人員在 5.6 Milestone Development Release版本中加入了 replication event checksum(主從複製事件校驗)功能。
相關閱讀:
MySQL 5.6主從複製第一部分[簡介及配置] http://www.linuxidc.com/Linux/2013-04/82712.htm
MySQL 5.6主從複製第二部分[恢復某一臺從服務器] http://www.linuxidc.com/Linux/2013-04/82713.htm
MySQL 5.6主從複製第三部分[把從服務器提升爲主服務器] http://www.linuxidc.com/Linux/2013-04/82714.htm
MySQL 5.6主從複製第四部分[一些被忽視的操作細節] http://www.linuxidc.com/Linux/2013-04/82715.htm
MySQL 主從複製事件校驗 MySQL Replication Event Checksum http://www.linuxidc.com/Linux/2013-04/82716.htm
使用pt-table-checksum檢查主從複製是否正常 http://www.linuxidc.com/Linux/2013-04/82717.htm
----------------------------------------分割線----------------------------------------
當一個event被寫入binary log(二進制日誌)的時候,checksum也同時寫入binary log,然後在event通過網絡傳輸到從服務器(slave)之後,再在從服務器中對其進行驗證並寫入從服務器的relay log.
由於每一步都記錄了event和checksum,所以我們可以很快地找出問題所在。
checksum使用zlib中的CRC-32算法,更具體地講,是ISO-3309 CRC-32算法,雖然此算法效率非常高,但總是帶來了一些額外的計算,至於會影響性能到怎樣的地步,目前還沒有benchmark。
[圖1]
如圖1所示,當箭頭離開thread的時候,就可以生成checksum;當箭頭進入thread的時候,就可以對checksum進行校驗了。
不過由於某些原因,並非在所有的箭頭處都進行了checksum。
event checksum功能,引入了三個新的參數:
binlog_checksum
默認爲NONE, 表示在圖1的箭頭1 不生成checksum, 這樣就可以兼容舊版本的mysql。
此外,就只能設置爲CRC32了。
master_verify_checksum
可以設置爲0或者1(默認爲0)。 對應於圖1中的箭頭2。
設置爲1的話,不僅dump thread會對event進行校驗,當master上執行show binlog events的時候,也會對event進行校驗。
設置爲1,可以保證event被完整無缺地寫入到主服務器的binlog中了。
不過,通常這個都設置爲0。
slave_sql_verify_checksum
與master_verify_checksum類似,這個也只能設置爲0或者1(默認爲1)。
設置爲1, 在圖1的箭頭4處會生成checksum,然後在箭頭5處會對checksum進行驗證。
看完這三個參數,再與圖1進行一下比較,會發現在箭頭3那裏沒有進行任何驗證。
原文中的解釋是:
在箭頭4的時候,當IO thread把event寫入到relay log的時候,會驗證checksum。
This is not necessary since the checksum is verified when the event is written to the relay log at point 4, and the I/O thread just does a straight copy of the event。
當checksum出錯的時候,會是怎樣的呢?試試看吧。
master> CREATE TABLE t1 (id INT AUTO_INCREMENT PRIMARY KEY, name CHAR(50));
Query OK, 0 ROWS affected (0.04 sec)
master> INSERT INTO t1(name) VALUES ('Mats'),('Luis');
Query OK, 2 ROWS affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
master> SHOW BINLOG EVENTS FROM 261;
+-------------------+-----+------------+-----------+-------------+-----------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+-------------------+-----+------------+-----------+-------------+-----------------------------------------------------------+
| master-bin.000001 | 261 | Query | 1 | 333 | BEGIN |
| master-bin.000001 | 333 | Intvar | 1 | 365 | INSERT_ID=1 |
| master-bin.000001 | 365 | Query | 1 | 477 | USE `test`; INSERT INTO t1(name) VALUES ('Mats'),('Luis') |
| master-bin.000001 | 477 | Query | 1 | 550 | COMMIT |
+-------------------+-----+------------+-----------+-------------+-----------------------------------------------------------+
4 ROWS IN SET (0.00 sec)