MySQL binlog中的事件類型

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

MySQL binlog記錄的所有操作實際上都有對應的事件類型的,譬如STATEMENT格式中的DML操作對應的是QUERY_EVENT類型,ROW格式下的DML操作對應的是ROWS_EVENT類型。 首先,看看源碼中定義的事件類型 源碼位置:mysql-5.7.14/libbinlogevents ...


MySQL binlog記錄的所有操作實際上都有對應的事件類型的,譬如STATEMENT格式中的DML操作對應的是QUERY_EVENT類型,ROW格式下的DML操作對應的是ROWS_EVENT類型。

首先,看看源碼中定義的事件類型

源碼位置:mysql-5.7.14/libbinlogevents/include/binlog_event.h

enum Log_event_type
{
  /**
    Every time you update this enum (when you add a type), you have to
    fix Format_description_event::Format_description_event().
  */
  UNKNOWN_EVENT= 0,
  START_EVENT_V3= 1,
  QUERY_EVENT= 2,
  STOP_EVENT= 3,
  ROTATE_EVENT= 4,
  INTVAR_EVENT= 5,
  LOAD_EVENT= 6,
  SLAVE_EVENT= 7,
  CREATE_FILE_EVENT= 8,
  APPEND_BLOCK_EVENT= 9,
  EXEC_LOAD_EVENT= 10,
  DELETE_FILE_EVENT= 11,
  /**
    NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longer
    sql_ex, allowing multibyte TERMINATED BY etc; both types share the
    same class (Load_event)
  */
  NEW_LOAD_EVENT= 12,
  RAND_EVENT= 13,
  USER_VAR_EVENT= 14,
  FORMAT_DESCRIPTION_EVENT= 15,
  XID_EVENT= 16,
  BEGIN_LOAD_QUERY_EVENT= 17,
  EXECUTE_LOAD_QUERY_EVENT= 18,

  TABLE_MAP_EVENT = 19,

  /**
    The PRE_GA event numbers were used for 5.1.0 to 5.1.15 and are
    therefore obsolete.
   */
  PRE_GA_WRITE_ROWS_EVENT = 20,
  PRE_GA_UPDATE_ROWS_EVENT = 21,
  PRE_GA_DELETE_ROWS_EVENT = 22,

  /**
    The V1 event numbers are used from 5.1.16 until mysql-trunk-xx
  */
  WRITE_ROWS_EVENT_V1 = 23,
  UPDATE_ROWS_EVENT_V1 = 24,
  DELETE_ROWS_EVENT_V1 = 25,

  /**
    Something out of the ordinary happened on the master
   */
  INCIDENT_EVENT= 26,

  /**
    Heartbeat event to be send by master at its idle time
    to ensure master's online status to slave
  */
  HEARTBEAT_LOG_EVENT= 27,

  /**
    In some situations, it is necessary to send over ignorable
    data to the slave: data that a slave can handle in case there
    is code for handling it, but which can be ignored if it is not
    recognized.
  */
  IGNORABLE_LOG_EVENT= 28,
  ROWS_QUERY_LOG_EVENT= 29,

  /** Version 2 of the Row events */
  WRITE_ROWS_EVENT = 30,
  UPDATE_ROWS_EVENT = 31,
  DELETE_ROWS_EVENT = 32,

  GTID_LOG_EVENT= 33,
  ANONYMOUS_GTID_LOG_EVENT= 34,

  PREVIOUS_GTIDS_LOG_EVENT= 35,

  TRANSACTION_CONTEXT_EVENT= 36,

  VIEW_CHANGE_EVENT= 37,

  /* Prepared XA transaction terminal event similar to Xid */
  XA_PREPARE_LOG_EVENT= 38,
  /**
    Add new events here - right above this comment!
    Existing events (except ENUM_END_EVENT) should never change their numbers
  */
  ENUM_END_EVENT /* end marker */
};

實際上還是蠻多的,下麵就挑幾個重點的說一下

 

QUERY_EVENT

QUERY_EVENT以文本的形式來記錄事務的操作。

QUERY_EVENT類型的事件通常在以下幾種情況下使用:

1. 事務開始時,執行的BEGIN操作。

2. STATEMENT格式中的DML操作

3. ROW格式中的DDL操作

譬如:

mysql> show binlog events in 'mysql-bin.000021';
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                          |
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------+
| mysql-bin.000021 |   4 | Format_desc |         1 |         120 | Server ver: 5.6.31-log, Binlog ver: 4         |
| mysql-bin.000021 | 120 | Query       |         1 |         195 | BEGIN                                         |
| mysql-bin.000021 | 195 | Query       |         1 |         298 | insert into test.t1 values(1,'a')             |
| mysql-bin.000021 | 298 | Xid         |         1 |         329 | COMMIT /* xid=25 */                           |
| mysql-bin.000021 | 329 | Query       |         1 |         408 | BEGIN                                         |
| mysql-bin.000021 | 408 | Query       |         1 |         515 | use `test`; insert into test.t1 values(2,'b') |
| mysql-bin.000021 | 515 | Xid         |         1 |         546 | COMMIT /* xid=33 */                           |
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------+

 

FORMAT_DESCRIPTION_EVENT

FORMAT_DESCRIPTION_EVENT是binlog version 4中為了取代之前版本中的START_EVENT_V3事件而引入的。它是binlog文件中的第一個事件,而且,該事件只會在binlog中出現一次。MySQL根據FORMAT_DESCRIPTION_EVENT的定義來解析其它事件。

它通常指定了MySQL Server的版本,binlog的版本,該binlog文件的創建時間。

譬如:

# at 4
#160817 11:00:10 server id 1  end_log_pos 120 CRC32 0x03010da1     Start: binlog v 4, server v 5.6.31-log created 160817 11:00:10
# Warning: this binlog is either in use or was not closed properly.
mysql> show binlog events in 'mysql-bin.000021';
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                          |
+------------------+-----+-------------+-----------+-------------+-----------------------------------------------+
| mysql-bin.000021 |   4 | Format_desc |         1 |         120 | Server ver: 5.6.31-log, Binlog ver: 4         |
...

 

ROWS_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操作,僅僅需要指定刪除的主鍵(在沒有主鍵的情況下,會給定所有列)

對於QUERY_EVENT事件,是以文本形式記錄DML操作的。而對於ROWS_EVENT事件,並不是文本形式,所以在通過mysqlbinlog查看基於ROW格式的binlog時,需要指定-vv --base64-output=decode-rows。

譬如:

mysql> show binlog events in 'mysql-bin.000027';
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                  |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000027 |   4 | Format_desc |         1 |         120 | Server ver: 5.6.31-log, Binlog ver: 4 |
| mysql-bin.000027 | 120 | Query       |         1 |         188 | BEGIN                                 |
| mysql-bin.000027 | 188 | Table_map   |         1 |         236 | table_id: 80 (test.t1)                |
| mysql-bin.000027 | 236 | Write_rows  |         1 |         278 | table_id: 80 flags: STMT_END_F        |
| mysql-bin.000027 | 278 | Xid         |         1 |         309 | COMMIT /* xid=198 */                  |
| mysql-bin.000027 | 309 | Query       |         1 |         377 | BEGIN                                 |
| mysql-bin.000027 | 377 | Table_map   |         1 |         425 | table_id: 80 (test.t1)                |
| mysql-bin.000027 | 425 | Update_rows |         1 |         475 | table_id: 80 flags: STMT_END_F        |
| mysql-bin.000027 | 475 | Xid         |         1 |         506 | COMMIT /* xid=199 */                  |
| mysql-bin.000027 | 506 | Query       |         1 |         574 | BEGIN                                 |
| mysql-bin.000027 | 574 | Table_map   |         1 |         622 | table_id: 80 (test.t1)                |
| mysql-bin.000027 | 622 | Delete_rows |         1 |         664 | table_id: 80 flags: STMT_END_F        |
| mysql-bin.000027 | 664 | Xid         |         1 |         695 | COMMIT /* xid=200 */                  |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
13 rows in set (0.00 sec)

 

XID_EVENT

在事務提交時,不管是STATEMENT還是ROW格式的binlog,都會在末尾添加一個XID_EVENT事件代表事務的結束。該事件記錄了該事務的ID,在MySQL進行崩潰恢復時,根據事務在binlog中的提交情況來決定是否提交存儲引擎中狀態為prepared的事務。

 

ROTATE_EVENT

當binlog文件的大小達到max_binlog_size的值或者執行flush logs命令時,binlog會發生切換,這個時候會在當前的binlog日誌添加一個ROTATE_EVENT事件,用於指定下一個日誌的名稱和位置。

mysql> show binlog events in 'mysql-bin.000028';
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                  |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000028 |   4 | Format_desc |         1 |         120 | Server ver: 5.6.31-log, Binlog ver: 4 |
| mysql-bin.000028 | 120 | Rotate      |         1 |         167 | mysql-bin.000029;pos=4                |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
2 rows in set (0.00 sec)
# at 120
#160817 12:34:26 server id 1  end_log_pos 167 CRC32 0xd965567c     Rotate to mysql-bin.000029  pos: 4

 

GTID_LOG_EVENT

在啟用GTID模式後,MySQL實際上為每個事務都分配了個GTID

譬如:

# at 448
#160818  5:37:32 server id 1  end_log_pos 496 CRC32 0xaeb24aac     GTID [commit=yes]
SET @@SESSION.GTID_NEXT= 'cad449f2-5d4f-11e6-b353-000c29c64704:3'/*!*/;
# at
496 #160818 5:37:32 server id 1 end_log_pos 571 CRC32 0x042ca092 Query thread_id=2 exec_time=0 error_code=0 SET TIMESTAMP=1471469852/*!*/; BEGIN /*!*/;
# at
571 #160818 5:37:32 server id 1 end_log_pos 674 CRC32 0xa35beb37 Query thread_id=2 exec_time=0 error_code=0 SET TIMESTAMP=1471469852/*!*/; insert into test.t1 values(2,'b') /*!*/;
# at
674 #160818 5:37:32 server id 1 end_log_pos 705 CRC32 0x1905d8c6 Xid = 12 COMMIT/*!*/;
mysql> show binlog events in 'mysql-bin.000033';
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                                              |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| mysql-bin.000033 |   4 | Format_desc    |         1 |         120 | Server ver: 5.6.31-log, Binlog ver: 4                             |
| mysql-bin.000033 | 120 | Previous_gtids |         1 |         191 | cad449f2-5d4f-11e6-b353-000c29c64704:1                            |
| mysql-bin.000033 | 191 | Gtid           |         1 |         239 | SET @@SESSION.GTID_NEXT= 'cad449f2-5d4f-11e6-b353-000c29c64704:2' |
| mysql-bin.000033 | 239 | Query          |         1 |         314 | BEGIN                                                             |
| mysql-bin.000033 | 314 | Query          |         1 |         417 | insert into test.t1 values(1,'a')                                 |
| mysql-bin.000033 | 417 | Xid            |         1 |         448 | COMMIT /* xid=11 */                                               |
| mysql-bin.000033 | 448 | Gtid           |         1 |         496 | SET @@SESSION.GTID_NEXT= 'cad449f2-5d4f-11e6-b353-000c29c64704:3' |
| mysql-bin.000033 | 496 | Query          |         1 |         571 | BEGIN                                                             |
| mysql-bin.000033 | 571 | Query          |         1 |         674 | insert into test.t1 values(2,'b')                                 |
| mysql-bin.000033 | 674 | Xid            |         1 |         705 | COMMIT /* xid=12 */                                               |
| mysql-bin.000033 | 705 | Rotate         |         1 |         752 | mysql-bin.000034;pos=4                                            |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
11 rows in set (0.00 sec)

 

PREVIOUS_GTIDS_LOG_EVENT

開啟GTID模式後,每個binlog開頭都會有一個PREVIOUS_GTIDS_LOG_EVENT事件,它的值是上一個binlog的PREVIOUS_GTIDS_LOG_EVENT+GTID_LOG_EVENT,實際上,在資料庫重啟的時候,需要重新填充gtid_executed的值,該值即是最新一個binlog的PREVIOUS_GTIDS_LOG_EVENT+GTID_LOG_EVENT。

譬如:

mysql> show binlog events in 'mysql-bin.000033';
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                                              |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| mysql-bin.000033 |   4 | Format_desc    |         1 |         120 | Server ver: 5.6.31-log, Binlog ver: 4                             |
| mysql-bin.000033 | 120 | Previous_gtids |         1 |         191 | cad449f2-5d4f-11e6-b353-000c29c64704:1                            |
| mysql-bin.000033 | 191 | Gtid           |         1 |         239 | SET @@SESSION.GTID_NEXT= 'cad449f2-5d4f-11e6-b353-000c29c64704:2' |
| mysql-bin.000033 | 239 | Query          |         1 |         314 | BEGIN                                                             |
| mysql-bin.000033 | 314 | Query          |         1 |         417 | insert into test.t1 values(1,'a')                                 |
| mysql-bin.000033 | 417 | Xid            |         1 |         448 | COMMIT /* xid=11 */                                               |
| mysql-bin.000033 | 448 | Gtid           |         1 |         496 | SET @@SESSION.GTID_NEXT= 'cad449f2-5d4f-11e6-b353-000c29c64704:3' |
| mysql-bin.000033 | 496 | Query          |         1 |         571 | BEGIN                                                             |
| mysql-bin.000033 | 571 | Query          |         1 |         674 | insert into test.t1 values(2,'b')                                 |
| mysql-bin.000033 | 674 | Xid            |         1 |         705 | COMMIT /* xid=12 */                                               |
| mysql-bin.000033 | 705 | Rotate         |         1 |         752 | mysql-bin.000034;pos=4                                            |
+------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
11 rows in set (0.00 sec)

mysql> show binlog events in 'mysql-bin.000034';
+------------------+-----+----------------+-----------+-------------+------------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                     |
+------------------+-----+----------------+-----------+-------------+------------------------------------------+
| mysql-bin.000034 |   4 | Format_desc    |         1 |         120 | Server ver: 5.6.31-log, Binlog ver: 4    |
| mysql-bin.000034 | 120 | Previous_gtids |         1 |         191 | cad449f2-5d4f-11e6-b353-000c29c64704:1-3 |
+------------------+-----+----------------+-----------+-------------+------------------------------------------+
2 rows in set (0.00 sec)

mysql-bin.000033日誌中的Previous_gtids是cad449f2-5d4f-11e6-b353-000c29c64704:1,GTID是cad449f2-5d4f-11e6-b353-000c29c64704:2和cad449f2-5d4f-11e6-b353-000c29c64704:3,這樣,在下一個日誌,即mysql-bin.000034中的Previous_gtids是cad449f2-5d4f-11e6-b353-000c29c64704:1-3。

# at 120
#160818  5:39:38 server id 1  end_log_pos 191 CRC32 0x4e84f3b5     Previous-GTIDs
# cad449f2-5d4f-11e6-b353-000c29c64704:1-3

 

STOP_EVENT

當MySQL資料庫停止時,會在當前的binlog末尾添加一個STOP_EVENT事件表示資料庫停止。


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

-Advertisement-
Play Games
更多相關文章
  • 第四章通過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. ...
  • 上文分析的二進位日誌實際上是基於STATEMENT格式的,下麵我們來看看基於ROW格式的二進位日誌,畢竟,兩者對應的binlog事件類型也不一樣,同時,很多童鞋反映基於ROW格式的二進位日誌無法查到原生的DML語句,關於這個問題,其實官方也給出瞭解決方案,下麵,將一一揭曉。 首先,來幾條測試數據 首 ...
  • 用批處理在命令行狀態下調用查詢分析器來執行這個sql文件里的語句。下麵就是sqlserver幫助里對於查詢分析器(isqlw)命令行參數的解釋:isqlw 實用工具(SQL 查詢分析器)使您得以輸入 Transact-SQL 語句、系統存儲過程和腳本文件。通過設置快捷方式或創建批處理文件,可以啟動預 ...
  • 介紹 1.下載解壓 下載地址:http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.14-winx64.zip 將下載的mysql解壓重命名放在C:\Program Files\MySQL\MySQL Server 5.7” 2.創建目錄 創建 ...
  • 在SQL Server中使用OPENROWSET訪問ORACLE資料庫時,你可能會遇到各種坑,下麵一一梳理一下你會遇到的一些坑。 1:資料庫沒有開啟"Ad Hoc Distributed Queries"選項,那麼你就會遇到下麵坑。 SELECT TOP 10 * FROM OPENROWSET('... ...
  • 一、功能介紹 1.MySQL Servers 該功能是mysql主要的服務,也是必須安裝的功能。 2.Mysql WorkBench 這個是mysql的客戶端工具,可以單獨下載安裝程式安裝。 3.Mysql Notifier 該功能可以控制mysql啟動,安裝了該功能會在電腦右下角的圖標中有控制my ...
  • 前幾天在開發一個系統,需要用到隨機字元串,但是mysql的庫函數有沒有直接提供,就簡單的利用現有的函數東拼西湊出隨機字元串來.下麵簡單的說下實現當時. 1.簡單粗暴. 上訴示例產生的是:6位長度的隨機字元串. 函數解釋: rand() :產生 0-1之間的小數,簡稱種子.rand()*25 產生的數 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...