mysql主從同步表結構不一致
最近在工作中遇到一個非常奇怪的問題,在兩臺主主同步的mysql資料庫中,經常出現修改表結構後,兩個庫中結構不一致的情況,檢視同步狀態,木有任何報錯,資料可正常同步,我自己在操作資料庫進行索引建立也可同步。接下來就開始了各種找根源,腦細胞極速死亡~
第一步:初探binlog
binlog檔案以Row模型進行儲存的(還可設定為Statement或Mixed),具體每種型別的區別網上很多(Binlog日誌模型),拉取binlog日誌需要用到mysqlbinlog,網上一番查詢,終於找到了引數詳情(mysqlbinlog命令引數詳解),這下終於可以看日誌了
# at 315449838
#181016 16:03:13 server id 2 end_log_pos 315450001 CRC32 0xb99978af Query thread_id=12181 exec_time=0 error_code=0
SET TIMESTAMP=1539676993/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=2, @@session.auto_increment_offset=2/*!*/;
alter TABLE XXXXdatabase.xxxTable ADD COLUMN resever2 INT
看完日誌,一臉懵逼,可以說語句寫得相當正常
抱著萬物皆有因的人生真諦,我開始了下一步的思考:
第二步:挖掘relay-log
在mysql同步中,主伺服器通過binlog日誌記錄操作事件,從伺服器通過IO執行緒讀取binlog日誌,生成relay-log日誌,再由從伺服器讀取relaylog執行操作。所以,博主開心的開始了檢視relay-log日誌過程,以下就是我檢視完之後的表情
relaylog中將binlog中的所有日誌都正常拉取到了,心中簡直就是十萬個為什麼,為什麼拉取到了“沒有執行”?如果執行了,為什麼執行效果和主備不一致?找Row模式的引數詳情,無解;找事件同步等級,無解。。。到此時,已經過去了大半天,罷了罷了,惹不起,不如回家做飯吃!!!果斷下班。。。
第三步:直擊人性
在下一個秋(bu)風(xiang)和(shang)煦(ban)的早上,不死心的我又開始了一番對比搗鼓,突然間,看到了前一天建立索引的binlog日誌資訊(用create建立的,所以一直以為是alter語句無法同步),腦海中神經突然碰撞連線,將create和alter的兩個事件日誌進行了360度無死角比對。
# at 315111302
#181016 14:50:56 server id 2 end_log_pos 315111456 CRC32 0x12c03d24 Query thread_id=12165 exec_time=3 error_code=0
use `XXXXdatabase`/*!*/;
SET TIMESTAMP=1539672656/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=2, @@session.auto_increment_offset=2/*!*/;
CREATE INDEX log_user_id_key ON xxxTable(user_id)
看到木有,這個比alter多了一個進庫的步驟,此刻心中已有了一個大膽的猜想,是不是alter時的語句格式有問題,在主從同步情況下,不支援直接在語句中引用資料庫?talk is cheap,show you code!,進入主伺服器,再進入資料庫,再執行
alter xxxTable ADD COLUMN resever2 INT
此刻,同步了。。了。。。了。。。。
再次拉取出binlog日誌如下:
# at 318394813
#181017 11:20:43 server id 2 end_log_pos 318394975 CRC32 0xecb8e18c Query thread_id=12316 exec_time=0 error_code=0
use `XXXXdatabase`/*!*/;
SET TIMESTAMP=1539746443/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=2, @@session.auto_increment_offset=2/*!*/;
alter xxxTable ADD COLUMN resever2 INT
至此,真相大白,線上的多次不同步竟是因為在執行sql語句時想要一步搞定偷懶所致。。。。可以說是很骨感很現實了。至於為什麼直接引用資料庫時無法正確執行,以後慢慢再去研究~