淺析MySQL基於ROW格式的二進位日誌

来源:http://www.cnblogs.com/ivictor/archive/2016/08/18/5780037.html
-Advertisement-
Play Games

上文分析的二進位日誌實際上是基於STATEMENT格式的,下麵我們來看看基於ROW格式的二進位日誌,畢竟,兩者對應的binlog事件類型也不一樣,同時,很多童鞋反映基於ROW格式的二進位日誌無法查到原生的DML語句,關於這個問題,其實官方也給出瞭解決方案,下麵,將一一揭曉。 首先,來幾條測試數據 首 ...


上文分析的二進位日誌實際上是基於STATEMENT格式的,下麵我們來看看基於ROW格式的二進位日誌,畢竟,兩者對應的binlog事件類型也不一樣,同時,很多童鞋反映基於ROW格式的二進位日誌無法查到原生的DML語句,關於這個問題,其實官方也給出瞭解決方案,下麵,將一一揭曉。

 

首先,來幾條測試數據

mysql> set binlog_format=row;
Query OK, 0 rows affected (0.00 sec)

mysql> flush logs;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into test.t1 values(1,'a');
Query OK, 1 row affected (0.00 sec)

mysql> use testDatabase changed
mysql
> insert into t1 values(2,'b'); Query OK, 1 row affected (0.00 sec) mysql> update t1 set name='c' where id=2; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> delete from t1 where id=1; Query OK, 1 row affected (0.01 sec)

 

首先通過SHOW BINLOG EVENTS查看二進位日誌中的內容

mysql> show binlog events in 'mysql-bin.000025';
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                  |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000025 |   4 | Format_desc |         1 |         120 | Server ver: 5.6.31-log, Binlog ver: 4 |
| mysql-bin.000025 | 120 | Query       |         1 |         188 | BEGIN                                 |
| mysql-bin.000025 | 188 | Table_map   |         1 |         236 | table_id: 79 (test.t1)                |
| mysql-bin.000025 | 236 | Write_rows  |         1 |         278 | table_id: 79 flags: STMT_END_F        |
| mysql-bin.000025 | 278 | Xid         |         1 |         309 | COMMIT /* xid=175 */                  |
| mysql-bin.000025 | 309 | Query       |         1 |         381 | BEGIN                                 |
| mysql-bin.000025 | 381 | Table_map   |         1 |         429 | table_id: 79 (test.t1)                |
| mysql-bin.000025 | 429 | Write_rows  |         1 |         471 | table_id: 79 flags: STMT_END_F        |
| mysql-bin.000025 | 471 | Xid         |         1 |         502 | COMMIT /* xid=183 */                  |
| mysql-bin.000025 | 502 | Query       |         1 |         574 | BEGIN                                 |
| mysql-bin.000025 | 574 | Table_map   |         1 |         622 | table_id: 79 (test.t1)                |
| mysql-bin.000025 | 622 | Update_rows |         1 |         672 | table_id: 79 flags: STMT_END_F        |
| mysql-bin.000025 | 672 | Xid         |         1 |         703 | COMMIT /* xid=184 */                  |
| mysql-bin.000025 | 703 | Query       |         1 |         775 | BEGIN                                 |
| mysql-bin.000025 | 775 | Table_map   |         1 |         823 | table_id: 79 (test.t1)                |
| mysql-bin.000025 | 823 | Delete_rows |         1 |         865 | table_id: 79 flags: STMT_END_F        |
| mysql-bin.000025 | 865 | Xid         |         1 |         896 | COMMIT /* xid=185 */                  |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
17 rows in set (0.00 sec)

 

再來通過mysqlbinlog查看

# mysqlbinlog mysql-bin.000025

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#160817 10:20:16 server id 1  end_log_pos 120 CRC32 0x5b15ac4f     Start: binlog v 4, server v 5.6.31-log created 160817 10:20:16
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
4MmzVw8BAAAAdAAAAHgAAAABAAQANS42LjMxLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAAU+s
FVs=
'/*!*/;
# at 120
#160817 10:20:22 server id 1  end_log_pos 188 CRC32 0x005847f0     Query    thread_id=12    exec_time=0    error_code=0
SET TIMESTAMP=1471400422/*!*/;
SET @@session.pseudo_thread_id=12/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1075838976/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 188
#160817 10:20:22 server id 1  end_log_pos 236 CRC32 0x2b8d2069     Table_map: `test`.`t1` mapped to number 79
# at 236
#160817 10:20:22 server id 1  end_log_pos 278 CRC32 0xadc98fbc     Write_rows: table id 79 flags: STMT_END_F

BINLOG '
5smzVxMBAAAAMAAAAOwAAAAAAE8AAAAAAAEABHRlc3QAAnQxAAIDDwIeAANpII0r
5smzVx4BAAAAKgAAABYBAAAAAE8AAAAAAAEAAgAC//wBAAAAAWG8j8mt
'/*!*/;
# at 278
#160817 10:20:22 server id 1  end_log_pos 309 CRC32 0x552dc682     Xid = 175
COMMIT/*!*/;
# at 309
#160817 10:20:34 server id 1  end_log_pos 381 CRC32 0x17d8173e     Query    thread_id=12    exec_time=0    error_code=0
SET TIMESTAMP=1471400434/*!*/;
BEGIN
/*!*/;
# at 381
#160817 10:20:34 server id 1  end_log_pos 429 CRC32 0x71a27e19     Table_map: `test`.`t1` mapped to number 79
# at 429
#160817 10:20:34 server id 1  end_log_pos 471 CRC32 0xefda98ca     Write_rows: table id 79 flags: STMT_END_F

BINLOG '
8smzVxMBAAAAMAAAAK0BAAAAAE8AAAAAAAEABHRlc3QAAnQxAAIDDwIeAAMZfqJx
8smzVx4BAAAAKgAAANcBAAAAAE8AAAAAAAEAAgAC//wCAAAAAWLKmNrv
'/*!*/;
# at 471
#160817 10:20:34 server id 1  end_log_pos 502 CRC32 0x7bed11c4     Xid = 183
COMMIT/*!*/;
# at 502
#160817 10:20:38 server id 1  end_log_pos 574 CRC32 0xd164b750     Query    thread_id=12    exec_time=0    error_code=0
SET TIMESTAMP=1471400438/*!*/;
BEGIN
/*!*/;
# at 574
#160817 10:20:38 server id 1  end_log_pos 622 CRC32 0x9fa3cabc     Table_map: `test`.`t1` mapped to number 79
# at 622
#160817 10:20:38 server id 1  end_log_pos 672 CRC32 0xb1646398     Update_rows: table id 79 flags: STMT_END_F

BINLOG '
9smzVxMBAAAAMAAAAG4CAAAAAE8AAAAAAAEABHRlc3QAAnQxAAIDDwIeAAO8yqOf
9smzVx8BAAAAMgAAAKACAAAAAE8AAAAAAAEAAgAC///8AgAAAAFi/AIAAAABY5hjZLE=
'/*!*/;
# at 672
#160817 10:20:38 server id 1  end_log_pos 703 CRC32 0x91a90c52     Xid = 184
COMMIT/*!*/;
# at 703
#160817 10:20:43 server id 1  end_log_pos 775 CRC32 0x5ae24c0b     Query    thread_id=12    exec_time=0    error_code=0
SET TIMESTAMP=1471400443/*!*/;
BEGIN
/*!*/;
# at 775
#160817 10:20:43 server id 1  end_log_pos 823 CRC32 0x33c52e84     Table_map: `test`.`t1` mapped to number 79
# at 823
#160817 10:20:43 server id 1  end_log_pos 865 CRC32 0x77e907a2     Delete_rows: table id 79 flags: STMT_END_F

BINLOG '
+8mzVxMBAAAAMAAAADcDAAAAAE8AAAAAAAEABHRlc3QAAnQxAAIDDwIeAAOELsUz
+8mzVyABAAAAKgAAAGEDAAAAAE8AAAAAAAEAAgAC//wBAAAAAWGiB+l3
'/*!*/;
# at 865
#160817 10:20:43 server id 1  end_log_pos 896 CRC32 0xb0988385     Xid = 185
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

 

額,what is this,竟然沒看到一條明文的DML語句

實際上,對於ROW格式的二進位日誌,需要使用如下方式查看,這也是STATEMENT和ROW格式的差異之一

# mysqlbinlog mysql-bin.000025 -vv --base64-output=decode-rows

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at
4 #160817 10:20:16 server id 1 end_log_pos 120 CRC32 0x5b15ac4f Start: binlog v 4, server v 5.6.31-log created 160817 10:20:16 # Warning: this binlog is either in use or was not closed properly.
# at
120 #160817 10:20:22 server id 1 end_log_pos 188 CRC32 0x005847f0 Query thread_id=12 exec_time=0 error_code=0 SET TIMESTAMP=1471400422/*!*/; SET @@session.pseudo_thread_id=12/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=1075838976/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/; SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; BEGIN /*!*/;
# at
188 #160817 10:20:22 server id 1 end_log_pos 236 CRC32 0x2b8d2069 Table_map: `test`.`t1` mapped to number 79 # at 236 #160817 10:20:22 server id 1 end_log_pos 278 CRC32 0xadc98fbc Write_rows: table id 79 flags: STMT_END_F ### INSERT INTO `test`.`t1` ### SET ### @1=1 /* INT meta=0 nullable=1 is_null=0 */ ### @2='a' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
# at 278 #160817 10:20:22 server id 1 end_log_pos 309 CRC32 0x552dc682 Xid = 175 COMMIT/*!*/;
# at
309 #160817 10:20:34 server id 1 end_log_pos 381 CRC32 0x17d8173e Query thread_id=12 exec_time=0 error_code=0 SET TIMESTAMP=1471400434/*!*/; BEGIN /*!*/;
# at
381 #160817 10:20:34 server id 1 end_log_pos 429 CRC32 0x71a27e19 Table_map: `test`.`t1` mapped to number 79
# at 429 #160817 10:20:34 server id 1 end_log_pos 471 CRC32 0xefda98ca Write_rows: table id 79 flags: STMT_END_F ### INSERT INTO `test`.`t1` ### SET ### @1=2 /* INT meta=0 nullable=1 is_null=0 */ ### @2='b' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
# at 471 #160817 10:20:34 server id 1 end_log_pos 502 CRC32 0x7bed11c4 Xid = 183 COMMIT/*!*/;
# at
502 #160817 10:20:38 server id 1 end_log_pos 574 CRC32 0xd164b750 Query thread_id=12 exec_time=0 error_code=0 SET TIMESTAMP=1471400438/*!*/; BEGIN /*!*/;
# at
574 #160817 10:20:38 server id 1 end_log_pos 622 CRC32 0x9fa3cabc Table_map: `test`.`t1` mapped to number 79
# at 622 #160817 10:20:38 server id 1 end_log_pos 672 CRC32 0xb1646398 Update_rows: table id 79 flags: STMT_END_F ### UPDATE `test`.`t1` ### WHERE ### @1=2 /* INT meta=0 nullable=1 is_null=0 */ ### @2='b' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */ ### SET ### @1=2 /* INT meta=0 nullable=1 is_null=0 */ ### @2='c' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
# at 672 #160817 10:20:38 server id 1 end_log_pos 703 CRC32 0x91a90c52 Xid = 184 COMMIT/*!*/;
# at
703 #160817 10:20:43 server id 1 end_log_pos 775 CRC32 0x5ae24c0b Query thread_id=12 exec_time=0 error_code=0 SET TIMESTAMP=1471400443/*!*/; BEGIN /*!*/;
# at
775 #160817 10:20:43 server id 1 end_log_pos 823 CRC32 0x33c52e84 Table_map: `test`.`t1` mapped to number 79
# at 823 #160817 10:20:43 server id 1 end_log_pos 865 CRC32 0x77e907a2 Delete_rows: table id 79 flags: STMT_END_F ### DELETE FROM `test`.`t1` ### WHERE ### @1=1 /* INT meta=0 nullable=1 is_null=0 */ ### @2='a' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
# at 865 #160817 10:20:43 server id 1 end_log_pos 896 CRC32 0xb0988385 Xid = 185 COMMIT/*!*/;
DELIMITER ; # End of log
file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

 

對於STATEMENT格式的binlog,所有的DML操作都記錄在QUERY_EVENT中,而對於ROW格式的binlog,所有的DML操作都記錄在ROWS_EVENT中,ROWS_EVENT分為三種:WRITE_ROWS_EVENT,UPDATE_ROWS_EVENT,DELETE_ROWS_EVENT,分別對應insert,update和delete操作。

對於insert操作,WRITE_ROWS_EVENT包含了要插入的數據

對於update操作,UPDATE_ROWS_EVENT不僅包含了修改後的數據,還包含了修改前的值。

對於delete操作,僅僅需要指定刪除的主鍵(在沒有主鍵的情況下,會給定所有列)

 

事實上,在ROW格式的binlog文件中, 每個ROWS_EVENT事件前都會有一個TABLE_MAP_EVENT,用於描述表的內部id和結構定義。

即便上述兩個insert操作,一個沒有執行use test操作,都不影響TABLE_MAP_EVENT的內容,這也會導致基於ROW格式下的庫級別的複製和基於STATEMENT格式下庫級別的複製的複製規則不一致。

 

如何在ROW格式中輸出原生的DML語句?

MySQL實際上提供了一個參數,可以用於輸出原生的DML語句,但是該語句僅僅是其註釋的作用,並不會被應用。

如下所示,

mysql> flush logs;
Query OK, 0 rows affected (0.01 sec)

mysql> set binlog_rows_query_log_events=1;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t1 values(3,'c');
Query OK, 1 row affected (0.00 sec)

 

對應的二進位的內容如下:

mysql> show binlog events in 'mysql-bin.000026';
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                  |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000026 |   4 | Format_desc |         1 |         120 | Server ver: 5.6.31-log, Binlog ver: 4 |
| mysql-bin.000026 | 120 | Query       |         1 |         192 | BEGIN                                 |
| mysql-bin.000026 | 192 | Rows_query  |         1 |         244 | # insert into t1 values(3,'c')        |
| mysql-bin.000026 | 244 | Table_map   |         1 |         292 | table_id: 79 (test.t1)                |
| mysql-bin.000026 | 292 | Write_rows  |         1 |         334 | table_id: 79 flags: STMT_END_F        |
| mysql-bin.000026 | 334 | Xid         |         1 |         365 | COMMIT /* xid=189 */                  |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
6 rows in set (0.00 sec)

實際上,MySQL新增了一個事務類型來輸出ROW格式中原生的DML語句,即ROWS_QUERY_EVENT。

 

自此以後,再也不用顧慮ROW格式的二進位日誌中無法查看原生的DML語句了。

 

參考

1. MariaDB原理與實現

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在應用圖標右上角添加消息數提醒,可以很方便的告知用戶該應用中有無新消息需要處理。下麵用xcode 7.3.1來簡要說明一下如何用swift語言進行此功能的實現。 1、修改 AppDelegate.swift 2 修改在ViewController.swift 3 編譯運行 第一次會彈出詢問是否允許推 ...
  • Socket 是應用層與 TCP / IP 協議通信的中間軟體抽象層,它是一組介面 TCP:面向連接、傳輸可靠(保證數據正確性,保證數據順序)、用於傳輸大量數據(流模式)、速度慢,建立連接需要開銷較多(時間,系統資源)。 UDP:面向非連接、傳輸不可靠、用於傳輸少量數據(數據包模式)、速度快 常用的 ...
  • 給工程師一個標準的估算項目時間 一個曾經與我一起工作過的經驗豐富的項目經理聲稱,他拿到程式員的時間估算以後,先將它乘以π,然後轉化下一個時間數量級後,才能得到真正的值。1天轉化成3.14周。他過去因為程式員不擅長估算時間而吃盡了苦頭。我創建了一個用來翻譯程式員時間估算的表格,來儘量縮小估算錯誤。 時 ...
  • 一,效果圖。 二,工程圖。 三,代碼。 RootViewController.h RootViewController.m ...
  • 之前對HTTPS通信過程有過瞭解,HTTPS是應用HTTP協議使用SSL加密的版本,在TCP和HTTP之間增加SSL協議。通過握手階段認證雙方身份,協商對稱秘鑰對通信信息進行加密。此處只描述常用的伺服器單向驗證,大致過程簡要描述如下: 0:事先Web伺服器把自己的公鑰和Web信息提交給權威CA,CA ...
  • 分析文本內容基本的步驟:提取文本中的詞語 -> 統計詞語頻率 -> 詞頻屬性可視化。詞頻:能反映詞語在文本中的重要性,一般越重要的詞語,在文本中出現的次數就會越多。詞雲:讓詞語的頻率屬性可視化,更加直觀清晰。文本下載地址(http://www.yuandn.com/booktxt/59797/#do ...
  • 第四章通過REmap包完成基於map分佈圖示例,前面提到REmap基於Echart2.0, 一方面在移動終端適應效果差,另一方面REmap提供的熱力圖僅支持全國及省市大版塊map,基於上面的原因,參考 http://echarts.baidu.com/examples.html#chart-type ...
  • 1. 可參考此文章:http://www.cnblogs.com/macro-cheng/archive/2011/10/25/mysql-001.html 2. 目前MySQL(我用的mysql 5.7.14)已經預設是utf-8編碼; 3. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...