官术网_书友最值得收藏!

2.4 重點Event之QUERY_EVENT和MAP_EVENT

2.4.1 QUERY_EVENT

1.QUERY_EVENT的作用

QUERY_EVENT不僅會記錄一些語句的運行環境,比如SQL_MODE、客戶端字符集、自增環境設置、當前登錄數據庫等,而且會記錄執行時間。但對于行模式的 DDL 和 DML 記錄的執行時間會有所不同,需要額外注意,如下。

DML:執行時間記錄的是第一條數據更改后的時間,而不是DML語句執行的時間(一個DML語句可能修改很多條數據)。這個時間往往非常短,不能正確地表示DML語句執行的時間。語句部分記錄的是begin。

DDL:執行時間記錄的是實際語句的執行時間,語句部分記錄的是實際的語句。

執行時間是 Seconds_Behind_Master 計算的一個影響因素,4.9 節將會詳細介紹Seconds_Behind_Master的計算公式。一個事務只有一個QUERY_EVENT。

2.源碼重要接口

主庫

· 初始化構造函數: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)。

從庫

· 讀取構造函數:Query_log_event::Query_log_event(char const*,uint,binary_log::Format_description_event const* ,binary_log::Log_event_type);

· 應用函數:Query_log_event::do_apply_event。

3.主體格式

QUERY_EVENT包含固定和可變兩部分,如圖2-5所示。

圖2-5

其中,固定部分如下。

slave_proxy_id:4字節,主庫生成Event的thread id,它和show processlist中的id對應。

query_exec_time:4字節,這是執行時間。但是對于行模式的 DML 語句,這個執行時間并不準確,上面已經描述了原因。而對于DDL,它還是比較準確的。

db_len:1字節,用于描述數據庫名的長度。

error_code:2字節,執行語句的錯誤碼。

status_vars_len:2字節,status variables部分的長度。

可變部分如下。

status variables:環境參數,其中包含很多種格式。每種格式都有自己的長度和數據域,因此可以輕松地讀取到各種值。比如SQL_MODE、客戶端字符集、自增環境、客戶端排序字符集等,但是其過于復雜,這里不做解析。

db:當前登錄的database名字,以0x00結尾。主庫來源為源碼變量thd->db。如果是語句模式,則從庫做過濾的時候會使用這個名字。

query:具體的語句。對于行模式的DML,記錄的是begin,而對于DDL,記錄的是具體的語句。

如果我們打開Query_log_event::do_apply_event函數,就會看到,這個Event在從庫應用的時候會設置各種環境,比如客戶端字符集、自增環境設置、當前登錄數據庫等,然后執行相應的語句,而對于行模式的DML,這里只會執行begin。注意一個細節,其中包含一段代碼:

這段代碼會設置線程的命令執行時間為Event header中Timestamp的時間,因此,我們在從庫上執行now()函數時,是可以得到正確的結果的。

4.實例解析

下面是一個行模式的DML的QUERY_EVENT(mysqlbinlog--hexdump輸出):

其中,固定部分如下。

06 00 00 00:thread id為6。

00 00 00 00:執行時間,對于行模式的DML來講通常不準。

04:當前登錄數據庫名的長度。

00 00:錯誤碼。

1a 00:status variables部分的長度,十六進制值1a就是十進制值26。

可變部分如下。

status variables:略。

74 65 73 74 00:當前登錄庫名test的ASCII編碼,以0x00結尾。

42 45 47 49 4e:語句BEGIN的ASCII編碼。

中間有一部分是status variables,這部分過于復雜,所以沒有做實際解析。

5.生成時機

對于行模式的DML而言,生成時機是在事務的第一個DML語句的第一行數據修改之后。通常來講,一個事務對應一個QUERY_EVENT。

DDL的生成時機在整個操作執行完成之后。

主站蜘蛛池模板: 金平| 汝城县| 涞水县| 宁津县| 黄浦区| 抚顺县| 和平区| 白朗县| 宜良县| 遵义市| 佛冈县| 安多县| 蓝田县| 武鸣县| 乌审旗| 新竹市| 攀枝花市| 曲靖市| 松潘县| 名山县| 万盛区| 绥中县| 贵港市| 塔城市| 四会市| 托克托县| 婺源县| 上杭县| 台江县| 三原县| 前郭尔| 关岭| 东宁县| 卢氏县| 清远市| 阳春市| 博罗县| 井研县| 延津县| 孝感市| 射洪县|