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