一些機緣巧合,認識了在測試領域做了很深入研究的 Manuel Rigger,也讀了他的三篇 Paper,算是收益匪淺吧,讓我從另一個角度來思考到底我們如何更好的測試 TiDB。
PQS
PQS 的 paper 是 Testing Database Engines via Pivoted Query Synthesis,原理其實很簡單的,如下圖:
- 隨機生成 table 和插入數據
- 從數據庫中隨機選擇一行數據
- 根據這行數據,隨機構造一個 expression
- 執行 expression,如果不爲 TRUE,調整爲 TRUE
- 將這個 expression 放到 where 或者 join 裏面
- 執行這條查詢語句
- 看最新的返回結果是不是還包含之前的那行數據,如果沒有,則表明有 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 進行數據庫測試,歡迎大家參與。