標籤:blog http 使用 io strong ar 問題 cti
MySQL Q&A 解析binlog的兩個問題
部落格分類:
mysqlbinlog字元集解析binlog格式
連續碰到兩個同學問類似的問題,必須要記錄一下。
問題:
一個作解析binlog應用的同學發現不論用utf8還是gbk來解析binlog都可能會碰到無法解析的語句,因為有些使用者會用utf8,有些用gbk。尤其在處理Query類型的SQL語句中的中文字元,比如建表語句中的中文注釋。
於是他想到用mysqlbinlog來看看binlog裡面的內容。
Mysqlbinlog這個工具的結果帶來了新的疑問。
開一個用戶端,執行序列如下:
set names utf8;
create table a(c int);
create table b(c int);
set names gbk;
drop table a;
create table a(c int)comment=‘測試字元集‘;
mysqlbinlog解析結果如下
binlog的結果與預期相同。從結果看,可以通過
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=28/*!*/;
這句話的原始資訊中得到當前使用的字元集,那麼解析後續的binlog語句就沒有問題。可以看到在drop table a之前我們修改了字元集,同樣在binlog解析結果中可以看到一個設定字元集的語句。
問題追問:但是解析工具是可以指定起始位置的。如果指定從drop table a這個語句的位置之後開始解析,那是不是就無法得知當前的字元集資訊(gbk)?是不是只能到MySQL server裡面才能得到這個表的正確建表語句?
顯然不會這麼複雜,否則MySQL的從庫上執行一個change master 改變同步位置的時候,從庫應該使用什麼字元集呢?碰到的問題是相同的。
實際上,對於statement格式的binlog(類型為QUERY_EVENT),每個event中都記錄了當前使用的字元集編號。無論主庫、從庫還是mysqlbinlog,都儲存相同的一份編號到字元集的對應,能夠決定使用什麼字元集來解析binlog中的字串。
這裡也可以得到為什麼官方無法保證從庫版本低於主庫版本的主從結構正確性的一個原因。
至於為什麼mysqlbinlog工具不會每行都輸出當前使用的字元集?其實有點潔癖的程式員都會這麼乾的吧,當前的語句與上一個語句使用相同的環境變數,就不重複輸出了。
問題2:mysqlbinlog結果中有use一個db以後,執行多個語句,此時mysqlbinlog的結果中看到,只會在切換的時候顯示一次use db。那如果從之後的第二個語句開始解析binlog,會不會導致這些語句執行到另外一個庫去?
同理。