Binlog由事件組成。請註意,事件不是事務,壹個事務可以包含多個事件。該事件描述了對數據庫的修改。
現在我們知道了Binlog的結構,我們可以嘗試修改Binlog中的數據。例如,在前面的示例中,Binlog刪除了壹條記錄,我們可以嘗試恢復這條記錄。Binlog中有壹個刪除行的事件(DELETE_ROWS_EVENT),它會刪除記錄。該事件的數據結構與寫行事件(WRITE_ROWS_EVENT)的數據結構完全相同,只是刪除行的事件類型為32,寫行的事件類型為30。我們將相應的Binlog位置放入。從前面的“顯示binlog事件”中,我們可以看到DELETE_ROWS_EVENT從位置378開始,這是Binlog文件的實際位置(以字節為單位)。從事件的結構中,我們可以看到type_code在事件的第五個字節中。我們可以編寫壹個Python小程序將第383(378+5 = 383)個字節更改為30。當然,您也可以使用二進制編輯工具來更改它。
在Binlog中查找大額交易
由於行模式下的Binlog會為每次更改記錄壹個日誌,因此壹個簡單的SQL可能會在Binlog中生成壹個巨大的事務,例如沒有where的update或delete語句,該語句會修改整個表中的所有記錄,並且每個記錄在Binlog中記錄壹次,從而產生壹個巨大的事務記錄。這樣的大事往往是麻煩的根源。我的壹個客戶曾經向我抱怨說,壹個原木向前滾動了兩天,但什麽也沒有發生。我解析了Binlog,發現有壹筆交易產生了1.4G條記錄,修改了66萬條記錄!下面是壹個簡單的Python小程序,用於找出Binlog中的大交易。我們知道,在mysqlbinlog解析的Binlog中,每個事務都以BEGIN開始,以COMMIT結束。讓我們在BENGIN之前找出“# at”的位置,並在COMMIT之後檢查“# at”的位置。通過減去這兩個頭寸可以計算出該交易的規模。以下是該Python程序的壹個示例。
在Binlog中削減大額交易
對於壹個大型事務,MySQL會將其分解為多個事件(註意壹個是事務,另壹個是事件),事件的大小由參數binlog-row-event-max-size決定,默認為8K。因此,我們可以將幾個事件分割成壹個稍小的事務。
在行模式下,即使我們只更新記錄中的壹個字段,也會記錄更改前後每個字段的值。此行為由binlog_row_image參數控制,該參數有三個值,默認值為FULL,即即使字段沒有更改,也將記錄對列的所有修改。這樣就可以實現類似甲骨文的閃回功能。我個人估計MySQL未來版本絕對不會推出基於Binlog的這樣壹個功能。
了解了Binlog的結構,再加上Python這種瑞士軍刀,我們可以實現很多功能。例如,我們可以統計哪個表被修改得最多。我們還可以將Binlog切成段然後重新組合,這樣可以靈活地修改和遷移MySQL數據庫。