淺析mysql-test框架

1 綜述

MTR框架分為兩部分:perl腳本(mysql-test-run.pl)和c++二進位(mysqltest)。perl腳本負責控制流程,包括啟停、識別執行哪些用例、創建文件夾、收集結果等等,mysqltest負責執行測試用例,包括讀文件,解析特定語法,執行用例。用例的特殊語法(比如,–source,–replace_column等)都在command_names和enum_commands兩個枚舉結構體中。

MTR框架時序圖如下所示:

2 Perl腳本控制框架

如上圖所示,mysql-test-run.pl框架運行流程如下:

1、初始化(Initialization)。確定用例執行範圍(collect_test_cases),包括運行哪些suite,skip哪些用例,在本階段根據disabled.def文件–skipXXX命令(比如skip-rpl)等確定執行用例。將所有用例組織到一個大的記憶體結構中,包括用例啟動參數,用例

同時,初始化資料庫(initialize_servers()->mysql_install_db()),後面運行用例啟動資料庫時,不需要每次初始化,只需從這裡的目錄中拷貝啟動

2、運行用例(run test)。主執行緒根據參數–parallel,默認是1)啟動一個或者多個用例執行執行緒(run_worker()),各執行緒有自己獨立的client port,data dir等。啟動的run_worker與主執行緒之間是server-client模式,主執行緒是server,run_worker()是client。主執行緒與run_worker是一問一答模式,主執行緒向run_worker發送運行用例的文件路徑、配置文件參數等各種參數資訊,run_worker向主執行緒返回運行結果,直到所有在collection中的用例都運行完畢,主執行緒close各run_worker,進行收尾工作

主執行緒先讀取各run_worker返回值,對上一個用例進行收尾工作。之後,讀取collection中的用例,通過本地socket發送到run_worker執行緒,run_worker執行緒接收到主執行緒命令,運行進去本次用例執行函數(run_testcase()),run_worker()的run_testcase()主要負責3件事:啟動mysqld、啟動並監控mysqltest,處理執行結果

啟動mysqld:run_testcase根據參數啟動一個或者多個mysqld(start_servers()),在start_servers大多數情況下會拷貝主執行緒初始化後的目錄到run_worker的目錄,作為新實例的啟動目錄,用shell命令啟動資料庫。

啟動並監控mysqltest:用例在mysqltest中執行,run_worker執行緒會監控mysqltest的運行狀態,監測其是否運行超時或者運行結束。

處理執行結果:mysqltest執行結束會留下執行日誌,框架根據執行日誌判斷執行是否通過,如果沒通過是否需要重試等

3 C++執行框架

執行框架都集中在mysqltest.cc中,mysqltest讀取用例文件(*.test),根據預定義的命令(比如–source,–replace_column, shutdown_server等)執行相應的操作。mysql根據run_worker傳入的運行參數(args)獲得用例文件路徑等資訊,然後讀取文件逐行執行語句,語句分為兩種,一種是可以直接執行的SQL語句,一種是控制語句,控制語句用來控制mysqlclient的特殊行為,比如shutdown mysqld等,這些命令預定義在command_names中


騰訊資料庫技術團隊對內支援QQ空間、微信紅包、騰訊廣告、騰訊音樂、騰訊新聞等公司自研業務,對外在騰訊雲上支援TencentDB相關產品,如CynosDB、CDB、CTSDB、CMongo等。騰訊資料庫技術團隊專註於持續優化資料庫內核和架構能力,提升資料庫性能和穩定性,為騰訊自研業務和騰訊雲客戶提供「省心、放心」的資料庫服務。此公眾號和廣大資料庫技術愛好者一起,推廣和分享資料庫領域專業知識,希望對大家有所幫助。