- 深入理解MySQL主從原理
- 高鵬
- 8字
- 2021-04-16 16:29:30
2.4 重點Event之QUERY_EVENT和MAP_EVENT
2.4.1 QUERY_EVENT
1.QUERY_EVENT的作用
QUERY_EVENT不僅會記錄一些語句的運行環(huán)境,比如SQL_MODE、客戶端字符集、自增環(huán)境設(shè)置、當(dāng)前登錄數(shù)據(jù)庫等,而且會記錄執(zhí)行時間。但對于行模式的 DDL 和 DML 記錄的執(zhí)行時間會有所不同,需要額外注意,如下。
DML:執(zhí)行時間記錄的是第一條數(shù)據(jù)更改后的時間,而不是DML語句執(zhí)行的時間(一個DML語句可能修改很多條數(shù)據(jù))。這個時間往往非常短,不能正確地表示DML語句執(zhí)行的時間。語句部分記錄的是begin。
DDL:執(zhí)行時間記錄的是實際語句的執(zhí)行時間,語句部分記錄的是實際的語句。
執(zhí)行時間是 Seconds_Behind_Master 計算的一個影響因素,4.9 節(jié)將會詳細(xì)介紹Seconds_Behind_Master的計算公式。一個事務(wù)只有一個QUERY_EVENT。
2.源碼重要接口
主庫
· 初始化構(gòu)造函數(shù):Query_log_event::Query_log_event(THD* ,char const* ,size_t,bool,bool,bool,int,bool);
· 寫入binlog cache:Query_log_event::write(IO_CACHE* file)。
從庫
· 讀取構(gòu)造函數(shù):Query_log_event::Query_log_event(char const*,uint,binary_log::Format_description_event const* ,binary_log::Log_event_type);
· 應(yīng)用函數(shù):Query_log_event::do_apply_event。
3.主體格式
QUERY_EVENT包含固定和可變兩部分,如圖2-5所示。

圖2-5
其中,固定部分如下。
slave_proxy_id:4字節(jié),主庫生成Event的thread id,它和show processlist中的id對應(yīng)。
query_exec_time:4字節(jié),這是執(zhí)行時間。但是對于行模式的 DML 語句,這個執(zhí)行時間并不準(zhǔn)確,上面已經(jīng)描述了原因。而對于DDL,它還是比較準(zhǔn)確的。
db_len:1字節(jié),用于描述數(shù)據(jù)庫名的長度。
error_code:2字節(jié),執(zhí)行語句的錯誤碼。
status_vars_len:2字節(jié),status variables部分的長度。
可變部分如下。
status variables:環(huán)境參數(shù),其中包含很多種格式。每種格式都有自己的長度和數(shù)據(jù)域,因此可以輕松地讀取到各種值。比如SQL_MODE、客戶端字符集、自增環(huán)境、客戶端排序字符集等,但是其過于復(fù)雜,這里不做解析。
db:當(dāng)前登錄的database名字,以0x00結(jié)尾。主庫來源為源碼變量thd->db。如果是語句模式,則從庫做過濾的時候會使用這個名字。
query:具體的語句。對于行模式的DML,記錄的是begin,而對于DDL,記錄的是具體的語句。
如果我們打開Query_log_event::do_apply_event函數(shù),就會看到,這個Event在從庫應(yīng)用的時候會設(shè)置各種環(huán)境,比如客戶端字符集、自增環(huán)境設(shè)置、當(dāng)前登錄數(shù)據(jù)庫等,然后執(zhí)行相應(yīng)的語句,而對于行模式的DML,這里只會執(zhí)行begin。注意一個細(xì)節(jié),其中包含一段代碼:

這段代碼會設(shè)置線程的命令執(zhí)行時間為Event header中Timestamp的時間,因此,我們在從庫上執(zhí)行now()函數(shù)時,是可以得到正確的結(jié)果的。
4.實例解析
下面是一個行模式的DML的QUERY_EVENT(mysqlbinlog--hexdump輸出):

其中,固定部分如下。
06 00 00 00:thread id為6。
00 00 00 00:執(zhí)行時間,對于行模式的DML來講通常不準(zhǔn)。
04:當(dāng)前登錄數(shù)據(jù)庫名的長度。
00 00:錯誤碼。
1a 00:status variables部分的長度,十六進制值1a就是十進制值26。
可變部分如下。
status variables:略。
74 65 73 74 00:當(dāng)前登錄庫名test的ASCII編碼,以0x00結(jié)尾。
42 45 47 49 4e:語句BEGIN的ASCII編碼。
中間有一部分是status variables,這部分過于復(fù)雜,所以沒有做實際解析。
5.生成時機
對于行模式的DML而言,生成時機是在事務(wù)的第一個DML語句的第一行數(shù)據(jù)修改之后。通常來講,一個事務(wù)對應(yīng)一個QUERY_EVENT。
DDL的生成時機在整個操作執(zhí)行完成之后。
- Instant Node Package Manager
- Spring Boot 2實戰(zhàn)之旅
- MySQL數(shù)據(jù)庫管理實戰(zhàn)
- Web Application Development with R Using Shiny(Second Edition)
- Servlet/JSP深入詳解
- aelf區(qū)塊鏈應(yīng)用架構(gòu)指南
- C語言程序設(shè)計案例式教程
- Python自然語言處理(微課版)
- 從學(xué)徒到高手:汽車電路識圖、故障檢測與維修技能全圖解
- Mastering macOS Programming
- C語言程序設(shè)計學(xué)習(xí)指導(dǎo)與習(xí)題解答
- Learning Python Design Patterns
- 飛槳PaddlePaddle深度學(xué)習(xí)實戰(zhàn)
- Integrating Facebook iOS SDK with Your Application
- Microsoft 365 Certified Fundamentals MS-900 Exam Guide