閱讀47 返回首頁    go 阿裏雲 go 技術社區[雲棲]


一條會施魔法的MySQL命令: STOP ALL SLAVES

作者介紹

婁帥北京萬裏開源公司數據庫技術專家,擅長MySQL運維及源碼研究。《Learning HBase》中文譯者。

原文:Playing with MySQL Source code; Adding “STOP ALL SLAVES” command,鏈接:https://mysql.az/2016/10/31/playing-with-mysql-source-code-adding-stop-all-slaves-command/

 

本文所要實現的功能來源於Charles Bell出版的《Expert MySQL》一書。《Expert MySQL》揭示了MySQL5.6.X版本的技術內幕,技術相對比較新且內容非常實用的一本書。

 

這裏要實現的功能是:

第八章“Extending MySQL High Availability”,第130頁,“Extending Replication”的功能。即添加一個新的命令“SQLCOM_STOP_SLAVES”,在master上執行,來停止所有的slave。實現方式是在master上執行"STOP ALL SLAVES"命令,通過binlog傳遞給slave並應用。

 

這裏基於MySQL5.6.32進行修改。

 

按照書中的提示,首先修改sql/lex.h文件,此文件中的符號數組是按照字母順序排序的。

 

修改如下:

20161123100216251.jpg

 

然後修改sql/sql_cmd.h文件,添加新的枚舉類型,在文件的開頭可以找enum_sql_command定義。

 

修改如下:

20161123100230824.jpg

 

接著需要添加新的語法中用到的標記。這裏的標記也是按照字母順序排序的。打sql/sql_yacc.yy文件,定位到對應的位置,添加我們新命令中需要的標記,這裏起名為SLAVES

 

1539/1540行修改如下:

20161123100249985.jpg

 

繼續修改“%type”定義的所在的段,將新標記添加進去。

 

1855/1856行修改如下:

20161123100258185.jpg

 

然後在命令列表裏麵添加新的命令,這樣解析器就可以解析到新的語法規則。注意,這裏我們使用'|'來添加新的規則。

 

2079/2080行修改如下:

20161123100307352.jpg

 

最後,我們添加新的語法規則來對應STOP ALL SLAVES命令。此規則隻需要將lex->sql_command設置為我們新增的枚舉類型即可。這樣就將語法的處理結果對應到最外層的命令處理函數的switch中的具體的枚舉值。

 

8114/8115行修改如下:

20161123100320684.jpg

 

YACC文件到此修改完成,下麵我們需要在switch中添加對應的新分支,完成寫binlog事件的操作。正常情況下,STOP SLAVE操作是不會被複製的。我們的代碼需要突破這個限製。打sql/sql_parse.cc文件,添加新的case分支。

 

3159/3160行修改如下:

20161123100338384.jpg

 

if條件用來判斷是否可寫binlog文件,如果可以寫,我們就將“STOP SLAVE IO_THREAD”事件寫到binlog中,注意,我們這裏使用了特殊的STOP SLAVE命令,僅僅是停止SLAVEIO

程。

 

這裏假設讀者已經熟悉如何編譯MySQL源碼。如果不會,請參

考-https://mysql.az/2015/08/18/installing-mysql-from-source-cmake-issues/

 

直接運行make,結果出現如下錯誤:

20161123100352231.jpg

 

作為源碼初學者,竟然意外的發現了書的bug。

 

看到了sql/sql_cmd.h文件中的如下注釋之後:

20161123100406726.jpg

 

了解到,新的命令需要添加到sql/mysqld.cc文件。但是並沒有找到 struct show_var_st status_vars[]數組,取而代之的是SHOW_VAR com_status_vars[],參見#83613

 

修改mysqld.cc文件的3571/3572行:

20161123100416103.jpg

 

保存後重新編譯,成功了!下麵就是部署住主從複製集群來測試添加的新功能。書中作者使用“MySQL Utilities“來部署。這裏我使用了“MySQL Sandbox”:

20161123100426605.jpg

 

這樣,一主兩從的集群就部署完成,可以進行測試了。

 

不幸的是,“stop all slaves”執行失敗,master出現了斷言錯誤:

20161123100436338.jpg

 

正常情況下,master執行完命令,應該返回Query OK。谘詢的Weixiang Zhai後,添加my_ok(thd)進行修複:

 

最終的sql/sql_parse.cc修改代碼如下:

20161123100534765.jpg

 

重新編譯並進行測試,master運行新增命令結果如下:

20161123100546620.jpg

 

slaves上的狀態如下:

20161123100558965.jpg

 

像施了魔法一樣。


原文發布時間為:2016-11-23

本文來自雲棲社區合作夥伴DBAplus

最後更新:2017-05-11 12:01:32

  上一篇:go  死鎖監控四步走,從此性能不再愁!
  下一篇:go  從架構到監控報警,支付係統的設計如何步步為營