數(shù)據(jù)異常在數(shù)據(jù)庫領(lǐng)域中較為常見,但目前業(yè)界內(nèi)并沒有關(guān)于數(shù)據(jù)異常的通用定義。騰訊金融云TDSQL首席架構(gòu)師李海翔老師攜手團隊對數(shù)據(jù)異常的本質(zhì)和價值進行研究,該研究成果目前已經(jīng)發(fā)表在《軟件學(xué)報》上,論文題目為《數(shù)據(jù)庫管理系統(tǒng)中數(shù)據(jù)異常體系化定義與分類》。
該文評審專家認為:本文系統(tǒng)地研究了數(shù)據(jù)庫的數(shù)據(jù)異常及其對應(yīng)的隔離級別,通過形式化的定義,總結(jié)和規(guī)范了數(shù)據(jù)異常的類型。基于形式化的解釋,解釋了不同數(shù)據(jù)異常之間的本質(zhì)區(qū)別。同時,本文還通過偏序關(guān)系對數(shù)據(jù)異常進行分類,并闡述了數(shù)據(jù)異常與隔離級別之間的關(guān)系。另外,本文深入總結(jié)了前人在數(shù)據(jù)異常領(lǐng)域的研究工作,文獻充實。文章具有極高的學(xué)術(shù)水平,作者分享了其在事務(wù)并發(fā)控制中數(shù)據(jù)異常和隔離級別上的深刻認知,另外作者也提供相應(yīng)的開源工具用來檢測數(shù)據(jù)異常,是一篇對事務(wù)并發(fā)控制方向非常有影響力的論文。
本次分享就是基于該篇論文的主要內(nèi)容,以下是分享實錄:
數(shù)據(jù)異常在數(shù)據(jù)庫中很常見,但數(shù)據(jù)異常的基本問題,其實并沒有得到很好的解決。比如在整個事務(wù)處理領(lǐng)域究竟有多少種數(shù)據(jù)異常?最開始SQL標(biāo)準(zhǔn)定義了4種數(shù)據(jù)異常,1995年Jim Gray等人在前者的基礎(chǔ)上又提出了4種新的數(shù)據(jù)異常。在閱讀了數(shù)百篇Paper后,我們也發(fā)現(xiàn)從1995年到2017年之間,不斷有人在提出新的數(shù)據(jù)異常,加起來有將近20種。
近幾年也陸續(xù)有人提出新的數(shù)據(jù)異常,包括2019年TDSQL也在分布式系統(tǒng)下報告了新的異常。比如下圖中提到的讀半已提交數(shù)據(jù)異常。
在一個分布式系統(tǒng)中,有兩個數(shù)據(jù)項,跨兩個物理節(jié)點,一個在A節(jié)點上,一個在B節(jié)點上。有一個分布式事務(wù),這個分布式事務(wù)是一個轉(zhuǎn)賬事務(wù),即寫X和Y,要給X減去10元,要給Y加10元。這時該事務(wù)是可以正常執(zhí)行的。但對于另一個只讀事務(wù)來說,當(dāng)它要跨兩個物理節(jié)點去讀數(shù)據(jù)時,它讀到的是數(shù)據(jù)舊的狀態(tài),在另一個節(jié)點又讀到了新的狀態(tài),一個新狀態(tài)和一個舊狀態(tài)是在一個事務(wù)之前的狀態(tài)和之后的狀態(tài),這兩個狀態(tài)跨越了一個事務(wù)的提交的一致性點,出現(xiàn)賬戶總額不匹配的情況,發(fā)生了數(shù)據(jù)不一致性現(xiàn)象(一致的情況是X+Y或者(X-10)+(Y+10),總和一定是X+Y),這就是我們所說的讀半已提交數(shù)據(jù)異常。
除了上述例子外,還有一些其他的數(shù)據(jù)異常,例如讀偏序、寫偏序等。我們會發(fā)現(xiàn),傳統(tǒng)的教科書,在提到數(shù)據(jù)異常的時候,總是一個一個的說臟讀、臟寫、寫偏序等數(shù)據(jù)異常分別是什么樣子。這些都是針對每一個具體的數(shù)據(jù)異常,去加以形式化的描述,并沒有一個關(guān)于數(shù)據(jù)異常的通用定義(即不能從數(shù)據(jù)異常整體上給出一個清晰定義)。那究竟什么是數(shù)據(jù)異常?這么多的數(shù)據(jù)異常之間究竟有什么關(guān)系?該如何用一個統(tǒng)一的方式或框架來理解所有的數(shù)據(jù)異常?這些都是沒有解決的問題。在事務(wù)處理領(lǐng)域,連“數(shù)據(jù)異常究竟有多少個”這樣的基本問題都不知道,不能回答,可見該領(lǐng)域還有很大空間。
為了理解數(shù)據(jù)異常,我們?nèi)ヌ剿髁藬?shù)據(jù)異常、變量和并發(fā)事務(wù)之間的關(guān)系。在這個問題的驅(qū)動下,我們把數(shù)據(jù)異常、變量、并發(fā)事務(wù)這些相關(guān)因素統(tǒng)一在一個模型下,再對數(shù)據(jù)異常加以形式化的定義,去找出每類數(shù)據(jù)異常的特征。這時我們發(fā)現(xiàn)數(shù)據(jù)異常其實有無窮多個。它不只是SQL標(biāo)準(zhǔn)所定義的4個數(shù)據(jù)異常,也不只是1995年Jim Gray等人定義的8種數(shù)據(jù)異常,其實,數(shù)據(jù)異常有無窮多個。
在數(shù)據(jù)異常有無窮多個的情況下,我們要如何去理解數(shù)據(jù)異常?這就要求必須對數(shù)據(jù)異常進行分類。我們用環(huán)形式化表達數(shù)據(jù)異常,對數(shù)據(jù)異常進行了特征研究。因為環(huán)的邊的種類是固定的,可以根據(jù)邊的種類可以對數(shù)據(jù)異常進行分類。分好類后,我們又進一步研究了非謂詞類的數(shù)據(jù)異常,比如臟讀、臟寫、不可重復(fù)讀和幻讀這樣的謂詞類數(shù)據(jù)異常,看它們之間有什么樣的關(guān)系。下圖藍色字體是TDSQL新報告的數(shù)據(jù)異常。
在理解了數(shù)據(jù)異常后,我們又去思考數(shù)據(jù)異常和一致性之間的關(guān)系。目前的事務(wù)處理領(lǐng)域的教科書,對一致性也沒有一個統(tǒng)一且完整的定義。
目前有兩種典型的說法:第一種,只提到“不違反完整性因素就叫符合一致性”。Jim Gray曾經(jīng)提出,從一個一致性狀態(tài)變遷到另一個合法的一致性狀態(tài),這就叫一致性。但這句話理解起來很抽象,存在認知上的困難。
第二種,源自Jim Gray的一篇Paper,作者們對一致性做過另一種形式的定義。該定義類似隔離級別,把一致性分成幾個級別,稱為degree0、degree1、degree2、degree3,并對每一種degree用具體規(guī)則來進行限定,具體的規(guī)則則是屏蔽了一定的數(shù)據(jù)異常。換句話說,Jim Gray其實給出了一個定義,即把一致性和數(shù)據(jù)異常聯(lián)系在一起,但他并沒有把所有的數(shù)據(jù)異常和一致性的定義聯(lián)系在一起(因為事務(wù)處理技術(shù)的發(fā)展歷史上,從沒有完整地定義過所有的數(shù)據(jù)異常,TDSQL系統(tǒng)化定義所有數(shù)據(jù)異常,是該領(lǐng)域內(nèi)首個對數(shù)據(jù)異常體系化定義的工作)。
我們又進一步去探索了數(shù)據(jù)一致性和數(shù)據(jù)異常之間的關(guān)系,再根據(jù)之前研究的結(jié)果對一致性下定義。這個定義描述起來很簡單,即一致性等于無數(shù)據(jù)異常。只要沒有數(shù)據(jù)異常那就符合數(shù)據(jù)一致性,反之,不一致就等于有數(shù)據(jù)異常。我們用數(shù)據(jù)異常去嘗試定義了數(shù)據(jù)的一致性。
在定義完數(shù)據(jù)一致性后,我們又做了一個新的探索,即研究數(shù)據(jù)異常和隔離級別之間的關(guān)系。當(dāng)我們在數(shù)據(jù)異常分類的基礎(chǔ)上嘗試去重新定義隔離級別時,我們發(fā)現(xiàn)隔離級別的定義非常靈活,它可以定義出不同級別或者不同粒度的一致性。
具體地說,我們基于數(shù)據(jù)異常這一體系,系統(tǒng)地提出了數(shù)據(jù)異常理論,再基于這樣形象化的定義嘗試去定義隔離級別。那怎么去定義隔離級別呢?因為掌握了全部數(shù)據(jù)異常,對數(shù)據(jù)異常的整體有了清晰認知,定義隔離級別就變?yōu)橐豁楈`活的工作,可以是粗粒度的隔離級別的定義,也可以是細粒度的隔離級別的定義。如果很細粒度地去劃分,我們可以分成多個層次,去定義成不同粒度的隔離級別,用以表達不同粒度的隔離級別和數(shù)據(jù)異常之間的本質(zhì)差異或本質(zhì)聯(lián)系。之所以能這樣做,是因為我們對于隔離級別,有了新的認知:隔離級別是數(shù)據(jù)異常的一種分類方法。
在靈活定義隔離級別后,對工程系統(tǒng)而言,就有了很大的幫助。如果用很復(fù)雜的隔離級別的定義去實現(xiàn)并發(fā)訪問控制,其實是比較難、比較復(fù)雜、容易出錯且低效率的。因此我們定義了一個簡化的隔離級別。簡化級別可以用于工程實際系統(tǒng)當(dāng)中,用一些規(guī)則就可以屏蔽掉很多數(shù)據(jù)異常,進而實現(xiàn)較好的性能。另外的一種隔離級別定義方式,較為細致,可以用于教學(xué)演示,演示數(shù)據(jù)異常之間的細膩差異,以幫助我們充分認知數(shù)據(jù)異常。
百尺竿頭更進一步。TDSQL沒有止步于系統(tǒng)地定義數(shù)據(jù)異常,除了把技術(shù)擴展到隔離級別外,我們更進一步地把數(shù)據(jù)異常體系化工作擴展到了并發(fā)訪問控制算法。以死鎖為例,死鎖是并發(fā)編程中常出現(xiàn)的問題,但死鎖的本質(zhì)是什么?Greenplum在2021 Sigmod上發(fā)表了一篇paper,該文提及了兩個分布式死鎖的例子。下圖中的這種死鎖,正是我們前述發(fā)現(xiàn)并定義的一種新的數(shù)據(jù)異常,稱為“Full-write Skew”異常。換句話說,死鎖就是一種數(shù)據(jù)異常。死鎖檢測算法就是數(shù)據(jù)異常的環(huán)檢測算法。這是我們研究成果價值另一方面的體現(xiàn)。