“mysqlbinlog”工具做binlog server靠譜嗎?

沃趣科技發表於2017-06-22

玩過binlog server的同學都知道,它使用mysqlbinlog命令以daemon程式的方式模擬一個slave的IO執行緒與主庫連線,可以很方便地即時同步主庫的binlog,以便彌補定時備份策略中最近一次備份到下一次備份完成之前這段時間內的資料容易丟失的問題。

  • 優點:備份出來的binlog不會受到主庫expire_logs_days引數的影響,因為binlog server是模擬slave的IO執行緒,也不會受到從庫relay_log_purge引數影響。這些binlog除非你手動清理,否則就會持續累計。so,你可以使用這些binlog+主庫的全備做基於時間點和pos點的資料恢復。

  • 缺點:因為binlog server是模擬slave的IO執行緒,所以在主庫crash的時間點,具有與真正的slave相同的來不及同步主庫最後一部分資料的風險。除此之外,binlog server本身也有bug。問題來了,這個bug是什麼bug?為什麼會有這個bug?這個bug在等到官方修復之前,有沒有什麼替代方案?請看下文分析過程


  • 背景

  • 資料庫版本:5.7.18

  • 資料庫關鍵配置引數 
    雙一,log_slave_updates,log-bin,slave_parallel_workers=16,binlog_rows_query_log_events=ON,server-id=3306250,slave_parallel_type=LOGICAL_CLOCK,slave_rows_search_algorithms='INDEX_SCAN,HASH_SCAN',innodb_page_cleaners=4

  • 資料庫IP:主庫IP 10.10.30.250,binlog server IP 10.10.30.217,下文中提到的伺服器資訊分別使用master和binlog server代替IP

  • 伺服器配置

  • CPU:16 vcpus

  • 記憶體:64G

  • 磁碟:100G flash卡

  • 網路卡:Speed: 100Mb/s

一 、建測試庫表


  • 建立資料庫


qogir_env@localhost : (none) 03:07:20> CREATE DATABASE `xiaoboluo`;


  • 建立表

qogir_env@localhost : (none) 03:07:20> CREATE TABLE `test` (

 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,

 `test` varchar(100) COLLATE utf8_bin DEFAULT NULL,

 `test2` varchar(100) COLLATE utf8_bin DEFAULT NULL,

 PRIMARY KEY (`id`)

) ENGINE=InnoDB;



二 、使用binlog server


  • 本文演示binlog server需要使用到mysqlbinlog的相關選項如下

  • –defaults-file=file_name:僅讀取該選項指定的配置檔案

  • –host=host_name, -h host_name:在使用binlog server時,指定從哪臺mysql server主機上獲取二進位制日誌

  • –password[=password], -p[password]:連線到伺服器時使用的密碼

  • –port=port_num, -P port_num:用於連線到遠端server的TCP / IP埠號

  • –raw:預設情況下,不使用–raw選項,mysqlbinlog讀取二進位制日誌檔案,並解析為文字格式輸出事件(直接列印在標準輸出中,可以使用輸出重定向到檔案中,也可以使用–result-file選項指定輸出檔案), –raw選項告訴mysqlbinlog仍然以讀取binlog時的原始二進位制格式輸出。該選項需要結合–read-from-remote-server選項使用

  • –read-from-remote-server, -R 
    1、使用該選項時,mysqlbinlog會偽裝成一個slave,連線讀取,請求指定的binlog file,主庫獲取接收到這個請求之後就建立一個binlog dump執行緒推送binlog給mysqlbinlog server。


    2、從MySQL server讀取二進位制日誌,而不是讀取本地日誌檔案。對於這些選項–host,–password,–port,–protocol,–socket和–user,除非給出了–read-from-remote-server選項結合使用,否則單獨指定這些TCP/IP連線選項將被忽略不生效

  • –result-file=name, -r name:不與–raw選項一併使用時,此選項指定一個mysqlbinlog解析的文字存放的檔案,當單獨使用–raw選項時,mysqlbinlog會使用從遠端server傳輸的原始binlog格式寫入本地檔案中,預設情況下輸出檔案與原始日誌檔案使用相同的檔名稱。如果與–raw選項一併使用時,–result-file選項值會修改輸出檔名的字首,如:原本是mysql-bin.000001,使用–result-file=binlog,則輸出檔名為binlogmysql-bin.000001

  • 更多選項資訊詳見官方文件連結:https://dev.mysql.com/doc/refman/5.7/en/mysqlbinlog.html

2.1. binlog server原始格式轉儲

  • 原始格式轉儲同步需要使用–raw選項,使用該選項時會以master例項中原始的binlog格式和檔名轉儲到binlog server本地系統指定目錄下存放,下面是演示步驟

  • 登入到master伺服器的資料庫例項中,執行重新整理日誌並檢視日誌檔案編號到多少了

qogir_env@localhost : (none) 03:13:05> flush logs;

Query OK, 0 rows affected (0.01 sec)

qogir_env@localhost : (none) 03:18:23> show binary logs;

| mysql-bin.000032 |   4721608 |

| mysql-bin.000033 |       281 |

| mysql-bin.000034 |      3273 |

| mysql-bin.000035 |      1777 |

| mysql-bin.000036 |      1777 |

| mysql-bin.000037 |       655 |

| mysql-bin.000038 |       234 |

+------------------+-----------+

38 rows in set (0.00 sec)


  • 從上面可以看到,最後一個binlog file是mysql-bin.000038,記錄下這個檔名登入到binlog server伺服器中,使用mysqlbinlog如下命令啟動一個binlog server程式(帶–raw選項)



# 先建立一個用於存放binlog server轉儲的檔案目錄,並進入到這個目錄下啟動mysqlbinlog程式,因為mysqlbinlog使用--raw選項時無法指定輸出路徑,只能轉儲到工作目錄下,所以需要先使用cd命令切換路徑

[root@4ee3a2ca-0be4-4057-a415-0ac5c05363ba ~]# mkdir /data/backup/binlogserver/

[root@4ee3a2ca-0be4-4057-a415-0ac5c05363ba ~]# cd /data/backup/binlogserver/

# 啟動mysqlbinlog程式並掛後臺執行

[root@4ee3a2ca-0be4-4057-a415-0ac5c05363ba binlogserver]# mysqlbinlog --host=10.10.30.250 --password=password --user=admin --read-from-remote-server mysql-bin.000038 --raw --stop-never &

# 檢視工作目錄,可以發現檔案已經被同步過來了,此時主庫還沒有寫入任何東西

[root@4ee3a2ca-0be4-4057-a415-0ac5c05363ba binlogserver]# ll

total 4

-rw-r----- 1 root root 123 May 22 16:08 mysql-bin.000038


  • 現在登入到master的資料庫例項中,寫入幾行測試資料,留意第二次insert語句的值改為了2017-05-23

qogir_env@localhost : (none) 03:51:47> insert into xiaoboluo.test(test) values('2017-05-22 00:03:26');

Query OK, 1 row affected (0.00 sec)

qogir_env@localhost : (none) 04:09:46> insert into xiaoboluo.test(test) values('2017-05-23 00:03:26');

Query OK, 1 row affected (0.00 sec)

qogir_env@localhost : (none) 04:09:50>


  • 到binlog server中解析binlog mysql-bin.000038,檢視轉儲的binlog內容

[root@4ee3a2ca-0be4-4057-a415-0ac5c05363ba binlogserver]# mysqlbinlog -vv  mysql-bin.000038

......   #這裡我們直接檢視最後一個事務,即最後一個BEGIN開始往後的內容即可

BEGIN

/*!*/;

# at 746

#170522 16:09:50 server id 3306250  end_log_pos 832 CRC32 0x434a1500    Rows_query

# insert into xiaoboluo.test(test) values('2017-05-23 00:03:26')

# at 832

#170522 16:09:50 server id 3306250  end_log_pos 890 CRC32 0x8fbe85a5    Table_map: `xiaoboluo`.`test` mapped to number 249

# at 890

#170522 16:09:50 server id 3306250  end_log_pos 951 CRC32 0x41154915    Write_rows: table id 249 flags: STMT_END_F

BINLOG '

zpwiWR0KczIAVgAAAEADAACAAD5pbnNlcnQgaW50byB4aWFvYm9sdW8udGVzdCh0ZXN0KSB2YWx1

ZXMoJzIwMTctMDUtMjMgMDA6MDM6MjYnKQAVSkM=

zpwiWRMKczIAOgAAAHoDAAAAAPkAAAAAAAEACXhpYW9ib2x1bwAEdGVzdAADAw8PBCwBLAEGpYW+

jw==

zpwiWR4KczIAPQAAALcDAAAAAPkAAAAAAAEAAgAD//z4wQIAEwAyMDE3LTA1LTIzIDAwOjAzOjI2

FUkVQQ==

'/*!*/;

### INSERT INTO `xiaoboluo`.`test`

### SET

###   @1=180728 /* INT meta=0 nullable=0 is_null=0 */

###   @2='2017-05-23 00:03:26' /* VARSTRING(300) meta=300 nullable=1 is_null=0 */  #這裡可以看到在master中寫入的第二行資料,日期為2017-05-23的那一行

###   @3=NULL /* VARSTRING(300) meta=300 nullable=1 is_null=1 */

ROLLBACK /* added by mysqlbinlog */ /*!*/;  #留意這裡,這裡按照正常邏輯來講,應該是一個帶commit語句和xid號的 event,然而這裡卻是一個rollback語句

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*/;

  • 從上面的結果中可以看到,master中第二個insert語句資料,binlog server透過mysqlbinlog命令轉儲之後,解析轉儲二進位制日誌檔案的輸出文字中並沒有打commit語句,也就是說,使用mysqlbinlog轉儲的binlog進行資料恢復時,第二個insert語句的資料將被回滾掉,導致資料丟失

  • 現在,登入到master中解析一下這個binlog檔案中第二個insert資料是如何記錄的呢


[root@e710d318-d5b4-4bc7-a606-d09f06ff5f5d binlog]# mysqlbinlog -vv  mysql-bin.000038

......

BEGIN

/*!*/;

# at 746

#170522 16:09:50 server id 3306250  end_log_pos 832 CRC32 0x434a1500    Rows_query

# insert into xiaoboluo.test(test) values('2017-05-23 00:03:26')

# at 832

#170522 16:09:50 server id 3306250  end_log_pos 890 CRC32 0x8fbe85a5    Table_map: `xiaoboluo`.`test` mapped to number 249

# at 890

#170522 16:09:50 server id 3306250  end_log_pos 951 CRC32 0x41154915    Write_rows: table id 249 flags: STMT_END_F

BINLOG '

zpwiWR0KczIAVgAAAEADAACAAD5pbnNlcnQgaW50byB4aWFvYm9sdW8udGVzdCh0ZXN0KSB2YWx1

ZXMoJzIwMTctMDUtMjMgMDA6MDM6MjYnKQAVSkM=

zpwiWRMKczIAOgAAAHoDAAAAAPkAAAAAAAEACXhpYW9ib2x1bwAEdGVzdAADAw8PBCwBLAEGpYW+

jw==

zpwiWR4KczIAPQAAALcDAAAAAPkAAAAAAAEAAgAD//z4wQIAEwAyMDE3LTA1LTIzIDAwOjAzOjI2

FUkVQQ==

'/*!*/;

### INSERT INTO `xiaoboluo`.`test`

### SET

###   @1=180728 /* INT meta=0 nullable=0 is_null=0 */

###   @2='2017-05-23 00:03:26' /* VARSTRING(300) meta=300 nullable=1 is_null=0 */  #日期為2017-05-23的資料在這裡

###   @3=NULL /* VARSTRING(300) meta=300 nullable=1 is_null=1 */

# at 951

#170522 16:09:50 server id 3306250  end_log_pos 982 CRC32 0x60d092ff    Xid = 1156777

COMMIT/*!*/;  # 可以看到master中記錄的binlog是正常的,代表這個事務在主庫已經正常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*/;

  • 透過以上解析結果對比可以看到,mysqlbinlog同步機制使用原始格式轉儲的binlog檔案中,最後一個事務原本應該是commit的語句,然而卻是rollback,為什麼會這樣呢?稍安勿躁,稍後見第3節總結部分,這裡我們們先看看binlog server文字格式轉儲是不是也有這個問題呢?



2.2.binlog server文字格式轉儲

  • 不使用–raw選項時,mysqlbinlog讀取master例項的binlog之後,在轉儲之前會解析為文字格式的事件日誌輸出,可以使用輸出重定向到一個檔案中儲存,也可以使用–result-file=file選項指定一個檔案進行存放,解析結果只能轉儲到同一個檔案中,主庫有新的binlog產生時,會在該檔案末尾持續追加,下面是演示步驟

  • 登入到binlog server伺服器中,停止mysqlbinlog程式並清空/data/backup/binlogserver目錄

[root@4ee3a2ca-0be4-4057-a415-0ac5c05363ba binlogserver]# killall mysqlbinlog

[root@4ee3a2ca-0be4-4057-a415-0ac5c05363ba binlogserver]# ps aux |grep mysqlbinlog

root     11878  0.0  0.0 103252   840 pts/0    S+   16:34   0:00 grep mysqlbinlog

[1]+  Terminated              mysqlbinlog --host=10.10.30.250 --password=password --user=admin --read-from-remote-server mysql-bin.000038 --raw --stop-never

[root@4ee3a2ca-0be4-4057-a415-0ac5c05363ba binlogserver]# rm -rf *

[root@4ee3a2ca-0be4-4057-a415-0ac5c05363ba binlogserver]# ll

total 0

[root@4ee3a2ca-0be4-4057-a415-0ac5c05363ba binlogserver]#

  • 登入到master伺服器的資料庫例項中,執行重新整理日誌並檢視日誌檔案編號到多少了

qogir_env@localhost : (none) 04:09:50> flush logs;

Query OK, 0 rows affected (0.01 sec)

qogir_env@localhost : (none) 04:35:04> show binary logs;

| mysql-bin.000034 |      3273 |

| mysql-bin.000035 |      1777 |

| mysql-bin.000036 |      1777 |

| mysql-bin.000037 |       655 |

| mysql-bin.000038 |      1029 |

| mysql-bin.000039 |       234 |

+------------------+-----------+

39 rows in set (0.00 sec)

  • 從上面可以看到,最後一個binlog file是mysql-bin.000039,記錄下這個檔名登入到binlog server伺服器中,使用mysqlbinlog如下命令啟動一個binlog server程式(不帶–raw選項,新增–result-file=binlog_parse)

[root@4ee3a2ca-0be4-4057-a415-0ac5c05363ba ~]# cd /data/backup/binlogserver/

# 啟動mysqlbinlog並掛後臺執行(注意:為了演示需要,把base-64編碼解析為可讀格式的sql語句,加上了-vv選項,實際生產環境如果要用於重放,請不要新增-vv選項)

[root@4ee3a2ca-0be4-4057-a415-0ac5c05363ba binlogserver]# mysqlbinlog --host=10.10.30.250 --password=password --user=admin --read-from-remote-server mysql-bin.000039 \

--result-file=binlog_parse --stop-never -vv &

# 檢視工作目錄,可以發現目錄下多了一個binlog_parse檔案,此時主庫還沒有寫入任何東西

[root@4ee3a2ca-0be4-4057-a415-0ac5c05363ba binlogserver]# ll

total 4

-rw-r----- 1 root root 741 May 22 16:38 binlog_parse

  • 現在登入到master的資料庫例項中,寫入幾行測試資料,留意這裡第二個insert的值改為了2017-05-23


qogir_env@localhost : (none) 04:35:11> insert into xiaoboluo.test(test) values('2017-05-22 00:03:26');

Query OK, 1 row affected (0.01 sec)

qogir_env@localhost : (none) 04:39:15> insert into xiaoboluo.test(test) values('2017-05-23 00:03:26');

Query OK, 1 row affected (0.00 sec)

qogir_env@localhost : (none) 04:39:18>

  • 到binlog server中檢視已經被mysqlbinlog命令解析並轉儲的binlog文字檔案binlog_parse

[root@4ee3a2ca-0be4-4057-a415-0ac5c05363ba binlogserver]# cat binlog_parse

......   #這裡我們直接檢視最後一個事務,即最後一個BEGIN開始往後的內容即可

BEGIN

/*!*/;

# at 746

#170522 16:39:18 server id 3306250  end_log_pos 832 CRC32 0xe3c8e631    Rows_query

# insert into xiaoboluo.test(test) values('2017-05-23 00:03:26')

# at 832

#170522 16:39:18 server id 3306250  end_log_pos 890 CRC32 0x7debb044    Table_map: `xiaoboluo`.`test` mapped to number 249

# at 890

#170522 16:39:18 server id 3306250  end_log_pos 951 CRC32 0xabb8de46    Write_rows: table id 249 flags: STMT_END_F

BINLOG '

tqMiWR0KczIAVgAAAEADAACAAD5pbnNlcnQgaW50byB4aWFvYm9sdW8udGVzdCh0ZXN0KSB2YWx1

ZXMoJzIwMTctMDUtMjMgMDA6MDM6MjYnKTHmyOM=

tqMiWRMKczIAOgAAAHoDAAAAAPkAAAAAAAEACXhpYW9ib2x1bwAEdGVzdAADAw8PBCwBLAEGRLDr

fQ==

tqMiWR4KczIAPQAAALcDAAAAAPkAAAAAAAEAAgAD//z8wQIAEwAyMDE3LTA1LTIzIDAwOjAzOjI2

Rt64qw==

'/*!*/;

### INSERT INTO `xiaoboluo`.`test`

### SET

###   @1=180732 /* INT meta=0 nullable=0 is_null=0 */

###   @2='2017-05-23 00:03:26' /* VARSTRING(300) meta=300 nullable=1 is_null=0 */  #日期為2017-05-23的event在這裡

###   @3=NULL /* VARSTRING(300) meta=300 nullable=1 is_null=1 */

# at 951

#170522 16:39:18 server id 3306250  end_log_pos 982 CRC32 0x29f585cc    Xid = 1156784

COMMIT/*!*/;  #這裡可以看到commit語句在不帶--raw時被正確轉儲了

  • 從上面的結果中可以看到,master中第二個insert語句插入的資料的commit標記被正確轉儲了,也就是說,binlog server透過mysqlbinlog命令轉儲的二進位制日誌在不使用–raw選項時(使用文字格式轉儲時),不會導致資料丟失

  • 現在,登入到master中解析一下這個binlog檔案中第二個Insert語句的資料,做個對比

[root@e710d318-d5b4-4bc7-a606-d09f06ff5f5d binlog]# mysqlbinlog -vv  mysql-bin.000038

......

BEGIN

/*!*/;

# at 746

#170522 16:39:18 server id 3306250  end_log_pos 832 CRC32 0xe3c8e631    Rows_query

# insert into xiaoboluo.test(test) values('2017-05-23 00:03:26')

# at 832

#170522 16:39:18 server id 3306250  end_log_pos 890 CRC32 0x7debb044    Table_map: `xiaoboluo`.`test` mapped to number 249

# at 890

#170522 16:39:18 server id 3306250  end_log_pos 951 CRC32 0xabb8de46    Write_rows: table id 249 flags: STMT_END_F

BINLOG '

tqMiWR0KczIAVgAAAEADAACAAD5pbnNlcnQgaW50byB4aWFvYm9sdW8udGVzdCh0ZXN0KSB2YWx1

ZXMoJzIwMTctMDUtMjMgMDA6MDM6MjYnKTHmyOM=

tqMiWRMKczIAOgAAAHoDAAAAAPkAAAAAAAEACXhpYW9ib2x1bwAEdGVzdAADAw8PBCwBLAEGRLDr

fQ==

tqMiWR4KczIAPQAAALcDAAAAAPkAAAAAAAEAAgAD//z8wQIAEwAyMDE3LTA1LTIzIDAwOjAzOjI2

Rt64qw==

'/*!*/;

### INSERT INTO `xiaoboluo`.`test`

### SET

###   @1=180732 /* INT meta=0 nullable=0 is_null=0 */

###   @2='2017-05-23 00:03:26' /* VARSTRING(300) meta=300 nullable=1 is_null=0 */

###   @3=NULL /* VARSTRING(300) meta=300 nullable=1 is_null=1 */

# at 951

#170522 16:39:18 server id 3306250  end_log_pos 982 CRC32 0x29f585cc    Xid = 1156784

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*/;

  • 從上面的結果中可以看到,文字格式轉儲並不會導致最後一個事務的commit被替換為rollback,你可以使用文字格式轉儲主庫binlog,雖然避免了資料丟失,但是問題也顯而易見…就是需要進行恢復時,因為是已經解析過的文字,所以不能使用–start-,–stop-這些選項來過濾查詢你想要的資料,需要手工來完成這個工作。資料量小還好,資料量大了就…不管怎樣,也勉強算是解決了原始格式轉儲的問題。至於你要不要用,那就見仁見智了。


三、總  結


  • 從2.1和2.2小節的對比演示可以看到

  • mysqlbinlog使用–raw選項以binlog日誌原始格式轉儲時,透過解析轉儲檔案發現來自master的最後一個事務的commmit標記缺失了,會導致利用mysqlbinlog轉儲的binlog檔案做資料恢復時,丟失最後一個事務,因為這最後一個事務原本是commit標記的位置使用的是rollback語句,會導致這最後一個事務被回滾掉,為什麼這個commit語句缺失了以及為什麼多了一個rollback語句?因為在mysqlbinlog工具的原始碼中,轉儲binlog檔案到磁碟是呼叫glibc來寫檔案,當mysqlbinlog偽裝的slave在連線master使用–raw+–read-from-remote-server 選項時,glibc的快取會把最後一個event留在記憶體中不呼叫fflush函式落盤(但master的binlog dump執行緒把mysqlbinlog的連線仍然當作一個正常的slave一樣把完整的binlog傳送過去給mysqlbinlog了),所以當你啟動另外一個mysqlbinlog程式去解析這個binlog檔案時,並沒有看到最後一個事務的commit標記,但是卻看到了rollback(這個rollback語句只要呼叫mysqlbinlog命令結束都會加上的,要注意,這個rollback語句是你用於解析這個binlog檔案的那一個mysqlbinlog程式加上的,跟binlog server的那一個mysqlbinlog沒關係,binlog server的那一個mysqlbinlog程式還仍然再執行中,還卡在最後一個commit未落盤這裡)

  • mysqlbinlog不使用–raw選項時,mysqlbinlog同步的binlog被直接解析為文字格式轉儲,這個時候轉儲的binlog內容中最後一個事務與主庫中記錄的一致,都帶有commit語句,即這個時候使用mysqlbinlog轉儲的binlog做資料恢復時,不會發生資料丟失,那這個時候為什麼有commit語句而沒有rollback語句呢?因為非raw模式的轉儲時(即只使用–read-from-remote-server 選項不使用–raw選項),mysqlbinlog解析時會呼叫glibc的fflush函式強制把快取中的資料重新整理到檔案中,所以不使用–raw選項時就會有commit語句,而缺失這個rollback語句是因為轉儲binlog的mysqlbinlog程式仍然在繼續執行,只有在mysqlbinlog結束的時候才會加上rollback語句。那為什麼使用–raw模式的時候mysqlbinlog也在執行,解析出來的binlog檔案就有rollback語句呢?還記得是另外呼叫了一個mysqlbinlog命令來解析的嗎?解析binlog的這個mysqlbinlog程式在執行完解析之後就退出了,so…

  • 因為binlog server在持續執行期間,最後一個事務的commit標記總是不落盤(除非你正常停止這個binlog server程式),所以,如果經濟上允許,建議單獨使用一臺伺服器,搭建一個備份專用備庫,還可以避免備份與線上業務訪問相互影響的問題,系統引數relay_log_purge別忘記設定為OFF,因為是備份binlog專用的備庫,所以表引擎可以改為blackhole引擎。

  • 注意:

  • mysqlbinlog server在加了–stop-never選項之後就會一直監聽所連線的server是否有新的events傳送過來,也正因為如此,導致了最後一個事務的commit語句一直不能落盤,直到主庫有新的events傳送過來時,這個事務的commit才會被觸發寫盤。如果不使用–stop-never選項當然就沒有問題,因為mysqlbinlog在讀取了server最後一個binlog檔案之後會退出,退出時會把快取中的events都落盤。但是這也會導致了無法即時轉儲主庫的資料更新。

  • 在MySQL 5.7.x版本中,mysqlbinlog工具解析任何一個本地的binlog或relay log時,都不會在mysqlbinlog命令執行結束時追加rollback語句,但在MySQL 5.6.x版本中,mysqlbinlog工具解析每一個本地binlog和relay log時在mysqlbinlog命令退出時都會加rollback語句


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28218939/viewspace-2141145/,如需轉載,請註明出處,否則將追究法律責任。

相關文章