主從數據庫複製時,主數據庫上有一個配置叫binlog_format,有3個選項(Mixed,Statement,Row)。具體說明可以參看官方文檔。
http://dev.mysql.com/doc/refman/5.7/en/replication-formats.html
Statement是語句級別的複製,簡單的說就是把主數據庫上執行的SQL語句在從庫上再執行一邊。
Row是行數據級別的複製,直接操作行級數據,這樣複製的準確性比Statement高。缺點是binlog記錄的數據量會變大。
Mixed是介於兩者之間的一種方式,Mysql會根據具體的SQL選擇Statement還是Row方式記錄。
Mixed在大部分情況下用Statement方式,但是在以下一些情況會以Row方式記錄,防止主從數據不一致。
1.UUID()
2.AUTO_INCREMENT
columns
3.When a statement refers to one or more system variables. 例如系統時間
其他還有很多,不過我在開發中沒遇到過,就不一一確認。
以下,我做了一些測試確認主從一致性。
先建立一張表
CREATE TABLE `test` (
`autoid` int(11) NOT NULL AUTO_INCREMENT,
`sysdatetime` datetime DEFAULT NULL,
`radomid` int(11) DEFAULT NULL,
`uuidhere` varchar(60) COLLATE utf8_bin DEFAULT NULL,
PRIMARY KEY (`autoid`)
)
插入數據
insert into test(sysdatetime,radomid,uuidhere) values(sysdate(),rand()*10000000,UUID())
檢索結果
autoid | sysdatetime | radomid | uuidhere | |
---|---|---|---|---|
1 | 2015-04-14 13:18:10 | 269932 | a4442c04-e265-11e4-80e1-00163e020999 | |
從庫檢查一下。數據也是一致的。
在從庫上,對自動增長key做一些手腳,讓兩邊不一致。
mysql> SELECT AUTO_INCREMENT FROM information_schema.tables WHERE table_name="test";
可以得到:AUTO_INCREMENT = 2
mysql> ALTER TABLE test auto_increment=4;
mysql> insert into test(sysdatetime,radomid,uuidhere) values(sysdate(),rand()*10000000,UUID());
mysql> select * from test;
4 | 2015-04-14 13:40:23 | 2215597 | bea0ffbb-e268-11e4-83c7-00163e000dcf
mysql> rollback;
mysql>
SELECT AUTO_INCREMENT FROM information_schema.tables WHERE table_name="test";
可以得到:AUTO_INCREMENT
= 5
然後再在主庫上插入數據,看同步情況。
1 | 2015-04-14 13:18:10 | 269932 | a4442c04-e265-11e4-80e1-00163e020999 |
2 | 2015-04-14 13:53:06 | 797249 | 85cebd3f-e26a-11e4-80e1-00163e020999 |