數據庫進階測試三部曲 - 從 PQS 到 NoREC 再到 TLP

一些機緣巧合,認識了在測試領域做了很深入研究的 Manuel Rigger,也讀了他的三篇 Paper,算是收益匪淺吧,讓我從另一個角度來思考到底我們如何更好的測試 TiDB。

PQS

PQS 的 paper 是 Testing Database Engines via Pivoted Query Synthesis,原理其實很簡單的,如下圖:

  1. 隨機生成 table 和插入數據
  2. 從數據庫中隨機選擇一行數據
  3. 根據這行數據,隨機構造一個 expression
  4. 執行 expression,如果不爲 TRUE,調整爲 TRUE
  5. 將這個 expression 放到 where 或者 join 裏面
  6. 執行這條查詢語句
  7. 看最新的返回結果是不是還包含之前的那行數據,如果沒有,則表明有 bug

是不是很簡單?當時我看完這篇 Paper 之後,真的有一種『我特麼怎麼想不到』這種感慨,Manuel 就通過這種簡單的方式給很多的數據庫,包括我認爲測試已經非常完備的 sqlite 找到了 bug。關於 sqlite 的測試,大家可以去看看 https://www.sqlite.org/testing.html

NoREC

NoREC 的 paper 是 Detecting Optimization Bugs in Database Engines via Non-Optimizing Reference Engine Construction,我看的時候,這篇 Paper 還是處於預覽版吧,原理照樣很簡單:

直白的說,就是將一條優化的 Query,強制變成非優化的方式,然後對比查詢結果,如果兩種執行方式不一致,那就是有 bug,是不是非常的簡單,是不是仍然有一種『我特麼的怎麼想不到』這種感慨。

相比於 PQS,NoREC 增強了對 aggregation 的判斷,譬如對於 group by 等操作,可以通過一些簡單的方式來驗證,譬如下圖使用的計數方式。

TLP

TLP 的 paper 是 Ternary Logic Partitioning: Detecting Logic Bugs in Database Management Systems,好吧,原理仍然很簡單,如下圖:

直白的說就是將一個 Query 分成了三個 Query,執行結果分別爲 TRUE,FALSE 和 NULL,然後再將這三個 Query 的結果合併,並且保證結果爲 TRUE。通過這種方式,在跟原始的結果對比,發現是否不一致。相比於 NoREC,TLP 能支持更多的 aggregation 操作,譬如:

讓我很高興的是,在 TLP 這篇 Paper 裏面,Manuel 終於開始正式使用 TiDB 作爲測試對象,當然幫我們發現了不少 bug,如下:

小結

Manuel 也一直在參加 TiDB 的 bug 挑戰賽,他通過 sqlancer 這個工具,幫 TiDB 發現了很多 bug,現在在挑戰賽排名上面也處於遙遙領先的狀態,我預計第一名應該非他莫屬了。另外,Manuel 也將會在 PingCAP 2020 DevCon 上面分享如何基於 TiDB 進行數據庫測試,歡迎大家參與。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章