天天看點

OceanBase品質保證——RD開發

OceanBase系統一直在不斷演化,需要在代碼不斷變化的過程中保持系統的穩定性。是以,合理的品質保證體系關乎系統的成敗。為了保證系統品質,OceanBase做了大量工作,在RD(指開發工程師)開發、QA(指測試工程師)測試、上線試運作各個階段對系統品質把關。

系統Bug暴露越早修複代價越低,開發工程師是産生Bug的源頭,開發階段主要通過編碼規範、代碼稽核(Code Revicw)、單元測試保證代碼品質。另外,系統提測前RD需要主動執行快速測試(quicktest),進而避免返工。

編碼規範

編碼規範規定了函數、變量、類型的命名規則,保證統一的注釋和排版風格。除此之外,為了避免C/C++伺服器端程式設計常見缺陷,OceanBase編碼規範還制定了一些規則,如下所示:

1) 一個函數隻能有一個人口和一個出口。不允許在函數中使用goto語句,也不允許函數中途return傳回。如下所示,上邊的代碼中途調用了return,在OceanBase編碼規範中是不允許的,可以修改為下邊的方式。這條規定有一定的争議,很多優秀的開源項目都允許函數中途return。之是以這麼規定,是為了確定函數執行過程中申請的資源被釋放掉。對于分布式存儲系統,代碼穩定運作的重要性遠遠高于代碼寫得更漂亮。

Alloc_memory();
If(x > 0)
{
  do_something1();
  free_memory();
  return true;
}
else
{
  do something2();
  free_memory();
  return false;
}           
boolean ret = true;
alloc_memory();
If(x > 0)
{
  do_something1();
  ret = true;
}
else
{
  do something2();
  ret=false;
}
free_memory();
return ret;           

2)禁止在函數中抛異常,謹慎使用STL、boost。C/C++程式設計的麻煩之處在于資源管理,尤其是記憶體管理。STL、boost庫接口容易使用,能夠提高編碼效率,但是記憶體管理混亂,不易調試,且大多數開發工程師不了解其内部實作,不适用于高性能伺服器的開發。

3)資源管理做到可控。所有的記憶體申請操作都需要經過OccanBase全局記憶體管理器,不允許直接在代碼中調用new/malloc申請記憶體。另外,系統初始化時啟動所有線程,執行過程中不允許動态啟動額外的線程。

4) 每個可能失敗的函數都必須傳回錯誤碼,0表示成功,其他值表示出錯。調用者需要仔細、全面地處理調用函數傳回的每個錯誤碼。

5)所有的指針使用前都必須判空,不允許使用assert語句替代錯誤檢查。這條規定是為了保證程式執行過程中出現異常情況時能夠列印錯誤日志而不是core dump。

6) 不允許使用strcpy/strca/strcpy/sprintf等字元串操作函數,而改用對應的限制字元申長度函數:strncpy/strncat/strncpy/snprintf,進而防止字元串操作越界。

7)嚴格要求自己,編譯時要開啟GCC所有報警開關,例如:-Wall-Werror

-Wextra-Wunused-paramcter-Wformat -Wconversion -Wdeprecated。代碼送出前需要確定解決所有的報警。

代碼稽核

OceanBase開發時要求所有代碼送出前至少由一人稽核,對于關鍵代碼改動,例如,緊急修複線上Bug,需要架構師和各個小組的技術負責人參與。

代碼稽核工作主要包含兩個部分:編碼風格稽核,比如是否符合編碼規範,接口設計是否合理,以及實作邏輯稽核。其中,實作邏輯稽核是難點,要求了解每個代碼實作細節,并給出建設性意見。每個剛剛加入團隊的新人都會配置設定一個師兄,師兄的其中一項職責就是稽核新人的代碼,與新人一起共同對代碼品質負責。

OceanBase采用開源的ReviewBoard(

http://www.reviewboard.org/)

作為代碼稽核系統。

單元測試

OceanBase 采用googletest以及google mock進行單元測試。單元測試的關鍵點在于系統接口設計時考慮可測性,并提高每個開發人員的單元測試意識。

OccanBase單元測試已接入一溝網内部開發的Toast平台,每天晚上會自動回歸所有的單元測試用例。Toast平台說明文檔見:

http://testing.etao.com/book/export/html/285

快速測試(quicktest)

快速測試選取所有測試用例的一個子集,這個子集中的每個用例執行都很快,進而做到快速回歸。快速測試部署成定時任務,每天自動回歸,RD送出某個功能的代碼之前也會主動運作快速測試,進而使得主幹代碼保持基本穩定。

RD壓力測試

分布式存儲引擎壓力測試

分布式存儲引擎壓力測試工具包含兩個:syschecker 以及mixed_test。在syschecker工具中,多個用戶端并發讀寫一行或者多行資料,并對讀取到的每行資料進行校驗。對于每行資料,其中的每一列都對應一個輔助列,二者資料之和為0。假設某列資料出錯,syschecker能夠很快檢測出來。

syschecker寫人速度很快,能夠發現分布式存儲引擎中的大部分問題,然面,syshecker隻校驗單行資料,不校驗多行資料之間的關系。是以,syschecker無法發現某行資料全部丢失的情況。mixed_test正是用來解決這個問題的,它不僅對每行資料進行校驗,還校驗多行資料之間的關系,能夠檢測出某行資料全部丢失的情況。當然,Mixed_test 寫入速度較慢,syschecker 和mixed_test兩個工具總是配合使用。各有優勢。

資料庫功能壓力測試

資料庫功能壓力測試工具包含兩個:sqltest以及bigquery。

  • sgltest工具測試時将指定一些SQL語句,sqltest工具會将這些語句分别發送給MySQL以及OceanBase資料庫。如果二者的執行結果相同,則認為sqltest測試通過;否則,測試失敗。
  • bigquery工具是sqltest工具的補充,專門用于測試OLAP并發查詢功能。Bigquery中每個查詢涉及的資料往往跨多個子表,能夠觸發OceanBase的并發查詢功能。當然,bigquery靈活性不夠,隻能執行特定的SQL語句,而sqltest能夠執行OceanBase支援的所有SOL語句。是以,bigquery 和sqltest兩個工具也是配合使用,各有優勢。

OceanBase早期測試資源嚴重不足,是以,要求開發在提測前必須運作一遍壓力測試。然而,這些壓力測試工具的維護非常耗時。2013年開始,RD壓力測試工具逐漸廢棄,其中的測試用例逐漸融合到QA壓力測試工具中。