解析MYSQL BINLOG 二進位制格式(1)--準備工作
原創:轉載請說明出處謝謝!
參考源:
1、原始碼log_event.h log_event.cc pack.c
2、internals-en.epub
一、目的
本系列檔案主要為了說明
1、為什麼說row格式較statement更佔空間
2、為什麼說row格式的binlog更加安全
3、INSERT/UPDATE/DELETE是生成的row binlog如何直接看懂二進位制格式
4、DDL生成的binlog是怎麼樣的
5、INSERT SELECT/CREATE TABLE 如何生成的row binlog
二、使用版本和數字顯示
本系列文章重要解釋MYSQL 5.6後row格式的binlog格式以及和事物有關的event,按照官方的說法
binlog的格式經歷了幾個階段
v1:mysql 3.23
v3:mysql 4.0.2 到 4.1
v4:mysql 5.0以上
v2版本只是短暫的存在過,當然我們要解析當然是v4版本的binlog
因為要看是5.6以上的binlog
關於多位元組的數字顯示,一般使用 Little-endian模式,做到和OS系統無關,除非刻意說明
關於Little-endian參考:
http://blog.itpub.net/7728585/viewspace-2124159/
三、binlog的魔法數
關於MYSQL BINLOG的作用就不做過多的解析了,在binlog中儲存的是一種稱之為event的條目,
它們以二進位制的格式儲存,平時我們使用的mysqlbinlog工具也就是對這種二進位制格式的檔案
進行解析,得到直觀的輸出。這裡不用mysqlbinlog而改為直接看二進位制檔案,當然我會對比
MYSQLBINLOG的輸出和二進位制解析的過程
每一個binlog檔案都有4位元組的魔法數,其值固定為
[root@testmy mysqld.1]# hexdump -Cv test.000005
可以看到
fe 62 69 6e .bin
四、binlog event的總體構架
一個event包括了
event header
event data
其中event data又分為
fixed data(posted header)
variable data
event header:全部的event統一固定的格式
fixed data(posted header):每一類event固定
variable data:就是可以變化實際值了
關於event的型別比較多詳細參考末尾原始碼的擷取
五、本系列文章要討論的event
而這裡我們只要討論5.6,5.7中和row binlog格式和innodb
聯絡比較緊密的幾種event如下:
query_log_event/QUERY_EVENT typecode=02
Format_description_log_event/FORMAT_DESCRIPTION_EVENT typecode=15
Xid_log_event/XID_EVENT typecode=16
Table_map_log_event/TABLE_MAP_EVENT typecode=19
Write_rows_log_event/WRITE_ROW_EVENT typecode=30
Update_rows_log_event/UPDATE_ROW_EVENT typecode=31
Delele_rows_log_event/DELETE_ROW_EVENT typecode=32
因為這些語句是一個事物必須經歷的,而Format_description_log_event是一個最重要的
說明性的event
六、通用標頭檔案(event header)解析
下面先解釋一下通用的19個位元組。
每一個event有一個固定的頭資訊叫做event header:
event header
timestamp 0:4
type_code 4:1
server_id 5:4
event_length 9:4
next_position 13:4
flags 17:2
timestamp:固定4位元組展示是新紀元(epoch time)以來的秒數
type_code:固定1位元組event事件的編碼,在原始碼中是一個enum型別負載最後原始碼處
server_id:固定4位元組就是 show variables like '%server_id';出來的值
event_length:固定4位元組整個event的長度,包含固定和非固定長度
next_position:固定4位元組下一個event的開始位置(2^32為4G)
flags:固定2位元組 event flags
LOG_EVENT_BINLOG_IN_USE_F 0x1 這個flags表示是否binlog正確的關閉了,這個標示只出現在Format_description_log_event中
LOG_EVENT_THREAD_SPECIFIC_F 0x4 是否查詢基於了臨時表,如果基於了臨時表MYSQLBINLOG必須設定 @@PSEUDO_THREAD_ID=xx
LOG_EVENT_SUPPRESS_USE_F 0x8 和--binlog-do-db 、 --replicated-do-db有關
其他還有很多
LOG_EVENT_ARTIFICIAL_F 0x20 LOG_EVENT_RELAY_LOG_F 0x40 LOG_EVENT_IGNORABLE_F 0x80 LOG_EVENT_NO_FILTER_F 0x100 。。。
可以自行參考log_event.h原始碼標頭檔案中的詳細解釋
七、packed interger
在binlog中部分數字使用這種方式顯示,在後面的解析中會提到
按照文件和原始碼中的說明
如果第一個位元組為0-250及0X0-0XFA那麼這個位元組就是實際顯示的數字值
原始碼的:
if (length < (ulonglong) LL(251))
{
*packet=(uchar) length;
return packet+1;
}
如果第一個位元組為252及0XFC那麼後面的2個位元組的值為0XFB-0XFFFF
原始碼的:
if (length < (ulonglong) LL(65536))
{
*packet++=252;
int2store(packet,(uint) length);
return packet+2;
}
如果第一個位元組為253及0XFD那麼後面的3個位元組的值為0XFFFF-0XFFFFFF
原始碼的:
if (length < (ulonglong) LL(16777216))
{
*packet++=253;
int3store(packet,(ulong) length);
return packet+3;
}
如果第一個位元組為254及0XFE那麼後面的8個位元組的值為0XFFFFFF-0XFFFFFFFFFFFFFFFF
*packet++=254;
int8store(packet,length);
可以自行參考原始碼介面,函式返回值為一個下一個位置的指標
uchar *net_store_length(uchar *packet, ulonglong length)
參考源:
1、原始碼log_event.h log_event.cc pack.c
2、internals-en.epub
一、目的
本系列檔案主要為了說明
1、為什麼說row格式較statement更佔空間
2、為什麼說row格式的binlog更加安全
3、INSERT/UPDATE/DELETE是生成的row binlog如何直接看懂二進位制格式
4、DDL生成的binlog是怎麼樣的
5、INSERT SELECT/CREATE TABLE 如何生成的row binlog
二、使用版本和數字顯示
本系列文章重要解釋MYSQL 5.6後row格式的binlog格式以及和事物有關的event,按照官方的說法
binlog的格式經歷了幾個階段
v1:mysql 3.23
v3:mysql 4.0.2 到 4.1
v4:mysql 5.0以上
v2版本只是短暫的存在過,當然我們要解析當然是v4版本的binlog
因為要看是5.6以上的binlog
關於多位元組的數字顯示,一般使用 Little-endian模式,做到和OS系統無關,除非刻意說明
關於Little-endian參考:
http://blog.itpub.net/7728585/viewspace-2124159/
三、binlog的魔法數
關於MYSQL BINLOG的作用就不做過多的解析了,在binlog中儲存的是一種稱之為event的條目,
它們以二進位制的格式儲存,平時我們使用的mysqlbinlog工具也就是對這種二進位制格式的檔案
進行解析,得到直觀的輸出。這裡不用mysqlbinlog而改為直接看二進位制檔案,當然我會對比
MYSQLBINLOG的輸出和二進位制解析的過程
每一個binlog檔案都有4位元組的魔法數,其值固定為
[root@testmy mysqld.1]# hexdump -Cv test.000005
可以看到
fe 62 69 6e .bin
四、binlog event的總體構架
一個event包括了
event header
event data
其中event data又分為
fixed data(posted header)
variable data
event header:全部的event統一固定的格式
fixed data(posted header):每一類event固定
variable data:就是可以變化實際值了
關於event的型別比較多詳細參考末尾原始碼的擷取
五、本系列文章要討論的event
而這裡我們只要討論5.6,5.7中和row binlog格式和innodb
聯絡比較緊密的幾種event如下:
query_log_event/QUERY_EVENT typecode=02
Format_description_log_event/FORMAT_DESCRIPTION_EVENT typecode=15
Xid_log_event/XID_EVENT typecode=16
Table_map_log_event/TABLE_MAP_EVENT typecode=19
Write_rows_log_event/WRITE_ROW_EVENT typecode=30
Update_rows_log_event/UPDATE_ROW_EVENT typecode=31
Delele_rows_log_event/DELETE_ROW_EVENT typecode=32
因為這些語句是一個事物必須經歷的,而Format_description_log_event是一個最重要的
說明性的event
六、通用標頭檔案(event header)解析
下面先解釋一下通用的19個位元組。
每一個event有一個固定的頭資訊叫做event header:
event header
timestamp 0:4
type_code 4:1
server_id 5:4
event_length 9:4
next_position 13:4
flags 17:2
timestamp:固定4位元組展示是新紀元(epoch time)以來的秒數
type_code:固定1位元組event事件的編碼,在原始碼中是一個enum型別負載最後原始碼處
server_id:固定4位元組就是 show variables like '%server_id';出來的值
event_length:固定4位元組整個event的長度,包含固定和非固定長度
next_position:固定4位元組下一個event的開始位置(2^32為4G)
flags:固定2位元組 event flags
LOG_EVENT_BINLOG_IN_USE_F 0x1 這個flags表示是否binlog正確的關閉了,這個標示只出現在Format_description_log_event中
LOG_EVENT_THREAD_SPECIFIC_F 0x4 是否查詢基於了臨時表,如果基於了臨時表MYSQLBINLOG必須設定 @@PSEUDO_THREAD_ID=xx
LOG_EVENT_SUPPRESS_USE_F 0x8 和--binlog-do-db 、 --replicated-do-db有關
其他還有很多
LOG_EVENT_ARTIFICIAL_F 0x20 LOG_EVENT_RELAY_LOG_F 0x40 LOG_EVENT_IGNORABLE_F 0x80 LOG_EVENT_NO_FILTER_F 0x100 。。。
可以自行參考log_event.h原始碼標頭檔案中的詳細解釋
七、packed interger
在binlog中部分數字使用這種方式顯示,在後面的解析中會提到
按照文件和原始碼中的說明
如果第一個位元組為0-250及0X0-0XFA那麼這個位元組就是實際顯示的數字值
原始碼的:
if (length < (ulonglong) LL(251))
{
*packet=(uchar) length;
return packet+1;
}
如果第一個位元組為252及0XFC那麼後面的2個位元組的值為0XFB-0XFFFF
原始碼的:
if (length < (ulonglong) LL(65536))
{
*packet++=252;
int2store(packet,(uint) length);
return packet+2;
}
如果第一個位元組為253及0XFD那麼後面的3個位元組的值為0XFFFF-0XFFFFFF
原始碼的:
if (length < (ulonglong) LL(16777216))
{
*packet++=253;
int3store(packet,(ulong) length);
return packet+3;
}
如果第一個位元組為254及0XFE那麼後面的8個位元組的值為0XFFFFFF-0XFFFFFFFFFFFFFFFF
*packet++=254;
int8store(packet,length);
可以自行參考原始碼介面,函式返回值為一個下一個位置的指標
uchar *net_store_length(uchar *packet, ulonglong length)
點選(此處)摺疊或開啟
-
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
-
Existing events (except ENUM_END_EVENT) should never change their numbers
-
*/
-
ENUM_END_EVENT /* end marker */
- };
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2133188/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL二進位制檔案(binlog)MySql
- websocket 二進位制資料傳輸基礎準備工作Web
- 如何在MySQL中檢視binlog二進位制日誌?MySql
- 二進位制求5個1的格式。。。。
- office檔案格式複合文件二進位制結構解析
- 二進位制備份還原案例
- 利用vstruct解析二進位制資料Struct
- 二進位制與二進位制運算
- MySQL二進位制日誌的三種格式優缺點比較MySql
- 進位制詳解:二進位制、八進位制和十六進位制
- JavaScript 二進位制、八進位制與十六進位制JavaScript
- MySQL 壓縮二進位制日誌MySql
- 【Linux合集】二進位制安裝mysqlLinuxMySql
- mysql 二進位制日誌總結MySql
- 二進位制中1的個數
- 遠端備份MySQL二進位制日誌--read-from-remote-serverMySqlREMServer
- 二進位制
- (二進位制)
- 十進位制——二 (八、十六 )進位制
- 二進位制,八進位制,十進位制,十六進位制的相互轉換
- 【進位制轉換】二進位制、十六進位制、十進位制、八進位制對應關係
- MySQL二進位制日誌Mixed格式轉化為row格式的六種情況總結MySql
- RHEL 7.2 安裝二進位制MySQL 5.7.18MySql
- centos 7 二進位制安裝mysql 5.7.25CentOSMySql
- Ubuntu 24.04 二進位制安裝 MySQL 8.0.20UbuntuMySql
- mysql二進位制日誌是什麼MySql
- 二進位制、十進位制與十六進位制相互轉化
- java中二進位制、八進位制、十進位制、十六進位制的轉換Java
- 二進位制,八進位制,十進位制,十六進位制之間的轉換
- 計算機基礎進位制轉換(二進位制、八進位制、十進位制、十六進位制)計算機
- 二進位制轉十進位制快速方法
- JAVA 二進位制,八進位制,十六進位制,十進位制間進行相互轉換Java
- Android逆向(一) —— AndroidManifest.xml 二進位制解析AndroidXML
- 什麼是二進位制?二進位制如何轉換?
- 二進位制小數和IEEE浮點標準
- Cocoapods 二進位制
- 04 二進位制
- leetcode -- 二進位制LeetCode
- 使用canal偷取MySQL的二進位制日誌MySql