您好,登錄后才能下訂單哦!
binlog的三種模式
statement模式
特點(diǎn):
(1)此模式不支持RU,RC隔離級別;
(2)binglog日志文件中上一個事物的結(jié)束點(diǎn)是下一個事物的開始點(diǎn);
(3)DML,DDL語句都會明文顯示;
(4)對一些系統(tǒng)函數(shù)不能準(zhǔn)確復(fù)制或者不能復(fù)制,如load_file()、uuid()、user()、found_rows()、sysdate(),注意(now()可以復(fù)制; )
(5)主庫執(zhí)行delete from t1 where c1=xxx limit 1,statement模式下,從庫也會這么執(zhí)行,可能導(dǎo)致刪除的不是同一行數(shù)據(jù)
(6)主庫有id=1和id=10兩行數(shù)據(jù),從庫有id=1,2,3,10這四行數(shù)據(jù),主庫執(zhí)行delete from t1 where id<10命令,從庫刪除過多數(shù)據(jù);
什么場景會用到statement模式:
(1)一次更新大量數(shù)據(jù),如二十萬數(shù)據(jù),否則在復(fù)制的時候,從庫可能會追的太慢,導(dǎo)致延時;
(2)使用pt-table-checksum工具時會使用到statement模式;
例1: set tx_isolation='repeatable-read'; set binlog_format='statement'; flush logs; create table t10(c1 int,c2 varchar(50)); insert into t10 values(1,now()); insert into t10 values(2,now()); insert into t10 values(3,sysdate()); insert into t10 values(4,uuid()); update t10 set c2='bbb' where c1=1; [root@Darren2 logs]# mysqlbinlog mysql-bin.000022 ...... create table t10(c1 int,c2 varchar(50)) BEGIN /*!*/; # at 532 #170408 14:40:49 server id 330622 end_log_pos 649 CRC32 0xe5cfc853 Query thread_id=55 exec_time=0 error_code=0 SET TIMESTAMP=1491633649/*!*/; --先設(shè)置timestamp,從庫復(fù)制的時候也會執(zhí)行這條SQL,這就是now()函數(shù)為什么可以復(fù)制的原因 insert into t10 values(1,now()) insert into t10 values(2,now()) insert into t10 values(3,sysdate()) insert into t10 values(4,uuid()) /*!*/; # at 1550 #170408 14:40:49 server id 330622 end_log_pos 1581 CRC32 0x5aaa5377 Xid = 1755 COMMIT/*!*/; # at 1581 #170408 14:40:49 server id 330622 end_log_pos 1646 CRC32 0xc2da517f GTID last_committed=5 sequence_number=6 SET @@SESSION.GTID_NEXT= '83373570-fe03-11e6-bb0a-000c29c1b8a9:11328'/*!*/; # at 1646 #170408 14:40:49 server id 330622 end_log_pos 1729 CRC32 0x943df058 Query thread_id=55 exec_time=0 error_code=0 SET TIMESTAMP=1491633649/*!*/; BEGIN /*!*/; # at 1729 #170408 14:40:49 server id 330622 end_log_pos 1841 CRC32 0xb443cf1e Query thread_id=55 exec_time=0 error_code=0 SET TIMESTAMP=1491633649/*!*/; update t10 set c2='bbb' where c1=1 /*!*/; # at 1841 #170408 14:40:49 server id 330622 end_log_pos 1872 CRC32 0xd06c40f5 Xid = 1756 COMMIT/*!*/; SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/; DELIMITER ; # End of log file /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; 主庫: root@localhost [testdb]>select * from t10; +------+--------------------------------------+ | c1 | c2 | +------+--------------------------------------+ | 1 | bbb | | 2 | 2017-04-08 14:40:49 | | 3 | 2017-04-08 14:40:49 | | 4 | 4d76efa5-1c26-11e7-bc58-000c29c1b8a9 | +------+--------------------------------------+ 從庫: root@localhost [testdb]>select * from t10; +------+--------------------------------------+ | c1 | c2 | +------+--------------------------------------+ | 1 | bbb | | 2 | 2017-04-08 14:40:49 | | 3 | 2017-04-14 13:12:19 | | 4 | ef119323-20d0-11e7-aef6-000c29565380 | +------+--------------------------------------+ 可以發(fā)現(xiàn),statument日志格式下,由于使用了一些函數(shù)導(dǎo)致主從數(shù)據(jù)不一致; 例2: update這個事物的開始是insert這個事物結(jié)束的點(diǎn)at1581; update結(jié)束的點(diǎn)是commit之后的點(diǎn)at1842; [root@Darren2 logs]# mysqlbinlog --start-position=1581 --stop-position=1842 mysql-bin.000022; ...... BEGIN /*!*/; # at 1729 #170408 14:40:49 server id 330622 end_log_pos 1841 CRC32 0xb443cf1e Query thread_id=55 exec_time=0 error_code=0 use `testdb`/*!*/; SET TIMESTAMP=1491633649/*!*/; update t10 set c2='bbb' where c1=1 /*!*/; # at 1841 #170408 14:40:49 server id 330622 end_log_pos 1872 CRC32 0xd06c40f5 Xid = 1756 COMMIT/*!*/; SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/; DELIMITER ; # End of log file /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; 例3: 當(dāng)查看commit之前的position點(diǎn)時,會看到rollback狀態(tài),說明這個截取的事物不完整: [root@Darren2 logs]# mysqlbinlog --start-position=1581 --stop-position=1841 mysql-bin.000022; BEGIN /*!*/; # at 1729 #170408 14:40:49 server id 330622 end_log_pos 1841 CRC32 0xb443cf1e Query thread_id=55 exec_time=0 error_code=0 use `testdb`/*!*/; SET TIMESTAMP=1491633649/*!*/; update t10 set c2='bbb' where c1=1 /*!*/; ROLLBACK /* added by mysqlbinlog */ /*!*/; SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/; DELIMITER ; # End of log file /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
row模式
(1)相對statement更加安全;
(2)在表有主鍵的情況下復(fù)制更加快;
(3)系統(tǒng)的特殊函數(shù)也能復(fù)制;
(4)更少的鎖,只有行鎖;
(5)binlog文件比較大,如單語句更新20萬行數(shù)據(jù),可能要半小時,也有可能把主庫跑掛;
(6)無法從binog看見用戶執(zhí)行的SQL語句(mysql 5.6后通過設(shè)置binlog_rows_query_log_events=on,日志格式為row中的binlog日志中看到執(zhí)行過得SQL語句。)
(7)5.7默認(rèn)的日志模式為row;
(8)DDL語句明文顯示,DML語句加密顯示;
(9)DML經(jīng)過base64加密,需要使用參數(shù)--base64-output=decode-rows --verbose;
(10)update修改的語句可以看到歷史舊數(shù)據(jù);
例1: set tx_isolation='repeatable-read'; set binlog_format='row'; flush logs; create table t10(c1 int,c2 varchar(50)); insert into t10 values(1,now()); insert into t10 values(2,now()); insert into t10 values(3,sysdate()); insert into t10 values(4,uuid()); update t10 set c2='bbb' where c1=1; 不加參數(shù)只能看到create,alter,drop等DDL語句: mysqlbinlog mysql-bin.000023 帶參數(shù)查看: [root@Darren2 logs]# mysqlbinlog -vv --base64-output=decode-rows mysql-bin.000023 ...... create table t10(c1 int,c2 varchar(50)) ### INSERT INTO `testdb`.`t10` ### SET ### @1=1 ### @2='2017-04-08 15:11:41' ### INSERT INTO `testdb`.`t10` ### SET ### @1=2 ### @2='2017-04-08 15:11:41' ### INSERT INTO `testdb`.`t10` ### SET ### @1=3 ### @2='2017-04-08 15:11:41' ### INSERT INTO `testdb`.`t10` ### SET ### @1=4 ### @2='9d96b424-1c2a-11e7-bc58-000c29c1b8a9' ### UPDATE `testdb`.`t10` ### WHERE ### @1=1 ### @2='2017-04-08 15:11:41' ### SET ### @1=1 ### @2='bbb' 例2:開啟binlog_rows_query_log_events參數(shù),會顯示執(zhí)行的SQL語句,這個參數(shù)默認(rèn)關(guān)閉,不顯示執(zhí)行的SQL root@localhost [testdb]>set binlog_rows_query_log_events=on; [root@Darren2 logs]# mysqlbinlog -vv --base64-output=decode-rows mysql-bin.000024 ...... create table t10(c1 int,c2 varchar(50)) # insert into t10 values(1,now()) ### INSERT INTO `testdb`.`t10` ### SET ### @1=1 /* INT meta=0 nullable=1 is_null=0 */ ### @2='2017-04-08 15:26:09' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */ # insert into t10 values(2,now()) ### INSERT INTO `testdb`.`t10` ### SET ### @1=2 /* INT meta=0 nullable=1 is_null=0 */ ### @2='2017-04-08 15:26:09' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */ # at 1033 # insert into t10 values(3,sysdate()) ### INSERT INTO `testdb`.`t10` ### SET ### @1=3 /* INT meta=0 nullable=1 is_null=0 */ ### @2='2017-04-08 15:26:09' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */ # insert into t10 values(4,uuid()) ### INSERT INTO `testdb`.`t10` ### SET ### @1=4 /* INT meta=0 nullable=1 is_null=0 */ ### @2='a2b570b8-1c2c-11e7-bc58-000c29c1b8a9' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */ # update t10 set c2='bbb' where c1=1 ### UPDATE `testdb`.`t10` ### WHERE ### @1=1 /* INT meta=0 nullable=1 is_null=0 */ ### @2='2017-04-08 15:26:09' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */ ### SET ### @1=1 /* INT meta=0 nullable=1 is_null=0 */ ### @2='bbb' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */
mixed模式
特點(diǎn):
(1)innodb引擎,如果隔離級別是RU、RC,則mixed模式會轉(zhuǎn)成Row模式存儲;
(2)mixed模式下,在以下幾種情況會自動將binlog的模式有SBR轉(zhuǎn)化成RBR模式:
當(dāng)更新一個NDB表時;
當(dāng)函數(shù)包含uuid()函數(shù)時;
2個及以上包含auto_increment字段的表被更新時;
視圖中必須要求使用RBR時,如創(chuàng)建視圖時使用了uuid()函數(shù);
例1:當(dāng)隔離級別是read-committed時,mixed模式會轉(zhuǎn)化成row模式存儲: set tx_isolation='read-committed'; set binlog_format='mixed'; flush logs; create table t10(c1 int,c2 varchar(50)); insert into t10 values(1,now()); insert into t10 values(2,now()); insert into t10 values(3,sysdate()); insert into t10 values(4,uuid()); update t10 set c2='bbb' where c1=1; [root@Darren2 logs]# mysqlbinlog -vv --base64-output=decode-rows mysql-bin.000028 ...... ### UPDATE `testdb`.`t10` ### WHERE ### @1=1 /* INT meta=0 nullable=1 is_null=0 */ ### @2='2017-04-08 18:34:08' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */ ### SET ### @1=1 /* INT meta=0 nullable=1 is_null=0 */ ### @2='bbb' /* VARSTRING(150) meta=150 nullable=1 is_null=0 */ ...... 例2:當(dāng)隔離級別是repeatable-read時,mixed模式會轉(zhuǎn)化成statement模式存儲 set tx_isolation='repeatable-read'; set binlog_format='mixed'; flush logs; create table t10(c1 int,c2 varchar(50)); insert into t10 values(1,now()); insert into t10 values(2,now()); insert into t10 values(3,sysdate()); insert into t10 values(4,uuid()); update t10 set c2='bbb' where c1=1; [root@Darren2 logs]# mysqlbinlog mysql-bin.000029 ...... update t10 set c2='bbb' where c1=1 ......
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。