CnosDB成為首個產(chǎn)品支持SQLancer的云原生時序數(shù)據(jù)庫

通過使用SQLancer,CnosDB技術(shù)團隊不僅找到并修正產(chǎn)品查詢的邏輯錯誤;并且?guī)椭嫌雾椖繕?gòu)建更穩(wěn)定的查詢引擎;CnosDB也成為了首個產(chǎn)品支持SQLancer的云原生時序數(shù)據(jù)庫。
1.CnosDB已支持SQLancer
充分、全面的測試是保障數(shù)據(jù)庫管理系統(tǒng)正確性的關(guān)鍵,查找邏輯錯誤是構(gòu)建可靠的數(shù)據(jù)庫的重要組成部分。CnosDB不光關(guān)注性能的極致釋放,也同樣關(guān)心結(jié)果的正確性和可重復(fù)性。
SQLancer,全稱為Synthesized Query Lancer,該工具是一款針對數(shù)據(jù)庫管理系統(tǒng)DBMS的自動化安全測試工具。該工具可以幫助廣大研究人員輕松識別應(yīng)用程序?qū)崿F(xiàn)中的邏輯漏洞。我們這里所指的邏輯漏洞,即能夠?qū)е翫BMS獲取錯誤結(jié)果集的安全漏洞(比如說忽略數(shù)據(jù)記錄等等)。SQLancer的工作是強調(diào)數(shù)據(jù)庫系統(tǒng)返回不一致或不合邏輯的結(jié)果。它用Java編寫,已經(jīng)支持多款數(shù)據(jù)庫,包括SQLite、MySQL、PostgreSQL、ClickHouse等。

SQLancer簡介,截圖來源SQLancer?GitHub(github.com/sqlancer/sqlancer)
近期CnosDB團隊及開源社區(qū)為 CnosDB 實現(xiàn)了 SQLancer 所支持的 TLP、NoREC 兩種測試方案,并合并到上游的 main 分支之中,成為首個支持SQLancer的云原生時序數(shù)據(jù)庫。
2.CnosDB實現(xiàn)SQLancer
SQLancer的CnosDB實現(xiàn)目前使用的是Restful API,并根據(jù)CnosDB提供的數(shù)據(jù)類型生成SQL表達式,能生成聚合查詢,關(guān)聯(lián)查詢的SQL。表達式包括算術(shù)運算和支持的大部分函數(shù)。接下來我們會講解SQLancer的執(zhí)行步驟和SQLancer的具體檢測方法。
2.1.SQLancer?的執(zhí)行步驟
SQLancer的主要執(zhí)行步驟有以下五個階段,分別是:
1.通過連接器,連接CnosDB。
2.在CnosDB中創(chuàng)建數(shù)據(jù)庫。
3.在CnosDB中創(chuàng)建幾張表。
4.往CnosDB表中插入數(shù)據(jù),插入的數(shù)據(jù)是常量,往往是一些邊界數(shù)據(jù)。比如最大的整數(shù),負數(shù),還有各種奇怪的UTF8字符串。
5.執(zhí)行所選擇的檢測方法。
2.2CnosDB支持SQLancer的檢測方法
CnosDB現(xiàn)階段支持TLP檢測和NoREC檢測兩種方法。
2.2.1TLP?檢測方法
TLP是Ternary Logic Partitioning的縮寫,TLP 是一種在數(shù)字電路設(shè)計中使用的技術(shù),其中信號可以被分配到三個狀態(tài)之一:1,0,或者未定義(X)。這種技術(shù)可以用于表示不確定性或不完整性,并且可以有助于縮小電路的實現(xiàn)復(fù)雜度。在數(shù)據(jù)庫查詢之中,就是將一個 Query 分成了三個 Query,執(zhí)行結(jié)果分別為 TRUE,F(xiàn)ALSE 和 NULL,然后再將這三個 Query 的結(jié)果合并,并且保證結(jié)果為 TRUE。通過這種方式,再跟原始的結(jié)果對比,發(fā)現(xiàn)是否不一致。
TLP的步驟如下:
1.從數(shù)據(jù)庫中隨機選擇幾張表;在選出的表中,隨機選擇幾列。
2.生成一個基本的不帶 WHERE 子句的 SQL 語句,并生成 WHERE 子句。
3.根據(jù)生成的 WHERE 子句,在基本 SQL 語句上添加 IS TRUE、IS FALSE、IS NULL 的謂詞,合成三個 SQL 語句。
4.通過 UNION 將三個 SQL 語句合并為一個。
5.執(zhí)行基本 SQL 語句和 UNION 后的 SQL 語句。
6.對結(jié)果行數(shù)進行比對,如果出現(xiàn)行數(shù)不同的情況,則說明出現(xiàn)異常。
2.2.2NoREC?檢測方法
NoREC是Non-Optimizing Reference Engine Construction的縮寫,是一種不進行優(yōu)化的引擎構(gòu)建方法。這種方法的目的是提供一種簡單的、不受優(yōu)化限制的參考實現(xiàn),以便在其他優(yōu)化的引擎和算法中進行對比。這種方法通常沒有考慮性能和效率,并且只是為了證明概念的正確性。NoREC的檢測就是將一條優(yōu)化的 Query,強制變成非優(yōu)化的方式,然后對比查詢結(jié)果,如果兩種執(zhí)行方式不一致,那就是有 bug了。
NoREC的步驟如下:
1.生成一個 SELCT COUNT(*) FROM table WHERE expr 的格式的SQL。
2.再生成一個?SELECT?SUM?(cnt)FROM?(SELECT?CAST?(expr??AS?BIGINT)?cnt?FROM?table)
3.執(zhí)行后比對結(jié)果值,如果值不相同,說明出現(xiàn)異常。
但因為CnosDB是時序數(shù)據(jù)庫,對Count(*)的優(yōu)化規(guī)則,只會掃描第一個Field列。所以我們不是用COUNT(*)生成SQL,而是COUNT第一個FIELD。
3.SQLancer的成果
通過實現(xiàn)SQLancer,CnosDB技術(shù)團隊及社區(qū)伙伴發(fā)現(xiàn)并處理15處潛在的邏輯錯誤Bug,進一步保障了 CnosDB 執(zhí)行的正確性。這里的Bug,有CnosDB自身的Bug,也有查詢引擎DataFusion的Bug。截止到2023年2月1日找到的Bug如下:
1.https://github.com/cnosdb/cnosdb/issues/852
2.https://github.com/cnosdb/cnosdb/issues/784
3.https://github.com/apache/arrow-datafusion/issues/4401
4.https://github.com/cnosdb/cnosdb/issues/830
5.https://github.com/apache/arrow-datafusion/issues/4843(該bug發(fā)現(xiàn)前已被datafusion修復(fù))
6.https://github.com/apache/arrow-datafusion/issues/4947
7.https://github.com/apache/arrow-datafusion/issues/3778
8.https://github.com/apache/arrow-datafusion/issues/4075
9.https://github.com/cnosdb/cnosdb/issues/782
10.https://github.com/cnosdb/cnosdb/issues/807
11.https://github.com/apache/arrow-datafusion/issues/4339
12.https://github.com/apache/arrow-datafusion/issues/4297
13.https://github.com/apache/arrow-datafusion/issues/4080
14.https://github.com/apache/arrow-datafusion/issues/3832
15.https://github.com/apache/arrow-datafusion/issues/3830
16.https://github.com/apache/arrow-datafusion/issues/4452
4.未支持PQS的原因
除了所介紹的TPL和NoREC,SQLancer還提供了PQS的檢測方法。PQS的全稱是Pivoted Query Synthesis,用邏輯方法生成新的查詢(通常是SQL查詢)以解決特定的問題。它通過對已有的查詢進行變換和合成,以找到更優(yōu)的查詢,并使用特定的評估函數(shù)來評估其質(zhì)量。
PQS的主要流程如下:
生成隨機的表格并向其中插入數(shù)據(jù)。
1.從數(shù)據(jù)庫中隨機選擇一行數(shù)據(jù)。
2.根據(jù)該行數(shù)據(jù)隨機構(gòu)建一個表達式。
3.執(zhí)行該表達式,如果結(jié)果不為 TRUE,則調(diào)整為 TRUE。
4.將該表達式放入 WHERE 或 JOIN 中。
5.執(zhí)行該查詢語句。
6.檢查最新的結(jié)果是否仍包含先前的那行數(shù)據(jù),如果不包含,則表示存在問題。
目前CnosDB還未支持PQS,原因如下:
1.由于CnosDB的時序數(shù)據(jù)庫的存儲引擎特性,目前并不存儲NULL值,也沒有相應(yīng)的NULL標(biāo)記。
2.在讀取一行數(shù)據(jù)時,如果該列不存在任何值,則以NULL值補充,以滿足查詢引擎的需求。
3.CnosDB的Tag可以被視為一種特殊的索引,與Field存儲方式不同,相同的TagSet(即一組Tag鍵值對)不需要在每一行都進行存儲。
4.對于CnosDB,具有相同時間戳和TagSet的數(shù)據(jù)行會進行合并去重。
5.CnosDB目前不支持表之間的交叉連接。
因為以上原因,支持PQS在檢測錯誤中變得無足輕重了。但通過系統(tǒng)的不斷迭代和升級,CnosDB開發(fā)團隊及社區(qū)也會重新評估支持PQS的可能性。
5.結(jié)語
以上就是CnosDB支持SQLancer的全部內(nèi)容了,歡迎熱愛數(shù)據(jù)庫及數(shù)據(jù)庫測試的小伙伴們關(guān)注我們微信公眾號、B站視頻號以及加入我們的社區(qū),我們將及時更新最近技術(shù)動態(tài)與技術(shù)內(nèi)幕,并期待與大家深入交流。
作者
Harbour,哈老師。熱愛技術(shù)的創(chuàng)業(yè)碼農(nóng),HIT計算機+廣告學(xué)學(xué)士,CMU計算機編譯方向博士肄業(yè),現(xiàn)潛心鉆研時序數(shù)據(jù)庫與數(shù)據(jù)庫教育領(lǐng)域。
參考文獻
1.Finding?Bugs?in?Database?Systems?via?Query?Partitioning, https://www.manuelrigger.at/preprints/TLP.pdf
2.Detecting?Optimization?Bugs?in?Database?Engines?via?Non-Optimizing?Reference?Engine?Construction,https://www.manuelrigger.at/preprints/NoREC.pdf
3.Testing?Database?Engines?via?Pivoted?Query?Synthesis,https://arxiv.org/abs/2001.04174
4.SQLancer?GitHub,https://github.com/sqlancer/sqlancer
CnosDB簡介
CnosDB是一款高性能、高易用性的開源分布式時序數(shù)據(jù)庫,現(xiàn)已正式發(fā)布及全部開源。
歡迎關(guān)注我們的社區(qū)網(wǎng)站:https://cn.cnosdb.com??