超多干货!支撑起腾讯公司计费业务的TDSQL(附PPT)
bluesea,騰訊金融云專家工程師,從事分布式數(shù)據(jù)庫TDSQL研發(fā)工作。出版著作:《數(shù)據(jù)庫查詢優(yōu)化器的藝術(shù) 原理解析與SQL性能優(yōu)化》、《數(shù)據(jù)庫事務(wù)處理的藝術(shù) 事務(wù)管理與并發(fā)控制》,廣受好評。同時,bluesea還是中國人民大學(xué)信息學(xué)院工程碩士企業(yè)導(dǎo)師。
?
TDSQL是一個穩(wěn)定運(yùn)行了十年之久的分布式數(shù)據(jù)庫,不僅支撐了騰訊公司的計(jì)費(fèi)業(yè)務(wù),而且還在微眾銀行等金融單位的核心業(yè)務(wù)系統(tǒng)穩(wěn)定、高效地運(yùn)行了四年之久。這幾年,TDSQL在技術(shù)層面不斷進(jìn)步,研發(fā)了很多新特性,諸如多級分區(qū)、熱點(diǎn)更新、隱含主鍵、分布式事務(wù)等,不僅有力的支撐了事務(wù)型的數(shù)據(jù)庫應(yīng)用,而且在體系結(jié)構(gòu)上也朝Spanner架構(gòu)上邁進(jìn),是一個名副其實(shí)的NewSQL系統(tǒng)。
MySQL/TDSQL的事務(wù)處理技術(shù),主要包括四個方面的內(nèi)容。其中,核心重點(diǎn)是并發(fā)控制技術(shù)。
第一,數(shù)據(jù)異常現(xiàn)象,這里不僅介紹有大家熟知的、SQL標(biāo)準(zhǔn)規(guī)定的三種讀數(shù)據(jù)異常,還有其他的八種異常,會極大擴(kuò)展大家對數(shù)據(jù)異常的認(rèn)識。
第二,MySQL的事務(wù)處理技術(shù),包括ACID的各個內(nèi)容。
第三,MySQL的并發(fā)訪問控制技術(shù)。并發(fā)控制技術(shù)是數(shù)據(jù)庫事務(wù)處理的核心技術(shù)。可以說,沒有事務(wù)處理,數(shù)據(jù)庫就不能算是數(shù)據(jù)庫;沒有并發(fā)控制技術(shù),事務(wù)處理也只是一個名詞而已。毫不夸張地說,并發(fā)控制技術(shù)是核心技術(shù)的核心。
第四,基于對MySQL的認(rèn)識,可以理解主流的數(shù)據(jù)如Oracle、Informix
數(shù)據(jù)異常
首先,我們談第一個問題:數(shù)據(jù)異常現(xiàn)象有哪些?
這列出了大家都熟悉的三種讀數(shù)據(jù)異常,分別是臟讀、不可重復(fù)讀、幻讀。我們看其中一個,比如說臟讀。第一步,T2事務(wù)修改了數(shù)據(jù)行row;第二步,T1事務(wù)對同一個數(shù)據(jù)行row讀取;第三步,T2事務(wù)回滾。這對于事務(wù)T1而言,讀到的數(shù)據(jù)是將被回滾的數(shù)據(jù),這就是臟讀。
有朋友會問,臟讀,也沒有什么大不了的。試想一下,一個騙子T2轉(zhuǎn)帳1000元給事務(wù)T1,事務(wù)T1檢查自己的賬戶,入賬了1000元,然后事務(wù)T1把一件衣服賣給了騙子T2,之后騙子T2拿到衣服后回滾了轉(zhuǎn)賬1000元的操作,然后逃之夭夭了。事務(wù)T1既沒有拿到錢還丟失了衣服,損失很大。所以要避免這樣的異常發(fā)生。
這三個讀異常現(xiàn)象,是大家熟知的,也是SQL標(biāo)準(zhǔn)所定義的數(shù)據(jù)異常現(xiàn)象。那么,除了讀異常,還有其他的數(shù)據(jù)異常嗎?
比如說臟寫。第一步,事務(wù)T1修改數(shù)據(jù)行row;第二步,事務(wù)T2也修改數(shù)據(jù)行row并提交,數(shù)據(jù)修改生效。事務(wù)T2認(rèn)為自己的操作是成功的。但不幸的事情發(fā)生了,第三步,事務(wù)T1回滾了,用舊值替換了被事務(wù)T2寫過的值。這意味著事務(wù)T2存入銀行的錢,丟失了,因?yàn)閹け旧现挥浿谝徊绞聞?wù)T1讀取的數(shù)據(jù)值。這就是寫數(shù)據(jù)發(fā)生的數(shù)據(jù)不一致的現(xiàn)象。
那么,除了這些讀和寫異常,還有其他的數(shù)據(jù)異常嗎?
接下來,我們繼續(xù)介紹兩種寫偏序異常:兩個事務(wù)寫偏序和三個事務(wù)寫偏序。
我們來看一下兩個事務(wù)寫偏序。首先,這里有個前提:醫(yī)院向社會承諾,至少有一名醫(yī)生對外提供電話咨詢服務(wù)。但是,如果有多于兩個醫(yī)生在提供電話咨詢,則需要某個正在進(jìn)行電話咨詢服務(wù)的醫(yī)生停止服務(wù)。
可是,大家看這兩個事務(wù)。事務(wù)T1發(fā)現(xiàn),有兩個以上的醫(yī)生正在提供電話咨詢,就請Alice停止電話服務(wù);事務(wù)T2也發(fā)現(xiàn)有兩個以上的醫(yī)生正在提供電話咨詢,就請Bob停止了電話服務(wù)。這樣,如果執(zhí)行前只有Alice和Bob正在提供電話服務(wù),這兩個事務(wù)執(zhí)行完畢后,沒有一個醫(yī)生在對外提供電話咨詢服務(wù)了。這就違背了“至少有一名醫(yī)生對外提供電話咨詢服務(wù)”的約束前提。這樣的現(xiàn)象,也是一種數(shù)據(jù)異常現(xiàn)象。
?
到現(xiàn)在為止,我們介紹了七種數(shù)據(jù)異常現(xiàn)象了。
這里,還例舉了四種數(shù)據(jù)異常,大家如果感興趣,可以翻閱《數(shù)據(jù)庫事務(wù)處理的藝術(shù)》一書。
?
我們一共提及了11種數(shù)據(jù)異常現(xiàn)象,有讀操作造成的三種讀異常,也有寫操作造成的兩種寫異常,還有寫操作涉及的兩種寫偏序異常等等。
?
對于數(shù)據(jù)庫系統(tǒng)而言,如果允許上面所說的數(shù)據(jù)不一致異常發(fā)生,我們這個依靠數(shù)據(jù)庫做交易的世界就會發(fā)生巨大混亂,數(shù)據(jù)庫在,賬面亂了。人活著,錢沒了。
那么,數(shù)據(jù)異常現(xiàn)象,是怎么產(chǎn)生的呢?
?
剛才談到的三種讀異常,有個一個共同點(diǎn),就是存在并發(fā)的事務(wù),這是第一個原因。剛才所談的四種讀寫組合,就是并發(fā)造成的。
第二,并發(fā)的事務(wù),操作的是同一個數(shù)據(jù)對象。
第三,并發(fā)的事務(wù)對同一個數(shù)據(jù)對象,進(jìn)行的總是讀寫或?qū)懽x或?qū)憣戇@三種,沒有讀讀。這就是上一個頁面里用黃色標(biāo)識的存在數(shù)據(jù)異常的三種情況。
第四,還有一種特殊情況,對于幻讀而言,受謂詞條件的影響,這時不是操作物理上的同一個已經(jīng)存在的對象,而是操作謂詞限定的同一個范圍內(nèi)的邏輯意義上的對象。我們把第四種情況概括為“謂詞的語義”。
這些合起來,造成了三種讀數(shù)據(jù)異常。
接下來,我們來分析一下寫偏序異常。
第一,存在并發(fā)的事務(wù)。
第二,并發(fā)的事務(wù),操作的不是同一個數(shù)據(jù)對象。這點(diǎn)和剛才的讀異常不同。
第三,并發(fā)的事務(wù)對不同的數(shù)據(jù)對象,進(jìn)行的總是讀寫或?qū)懽x或?qū)憣戇@三種,沒有讀讀并發(fā)。
第四,?? 操作結(jié)果,違反了“語義前提”。
請看第四點(diǎn),操作數(shù)據(jù)時,需要遵守一個語義前提,即“至少有一名醫(yī)生對外提供電話咨詢服務(wù)”,但是并發(fā)操作打破了這個語義前提,出現(xiàn)了沒有醫(yī)生提供咨詢的異常現(xiàn)象。
?
在數(shù)據(jù)庫里,數(shù)據(jù)操作會被抽象為兩種,就是讀操作和寫操作。
讀寫操作組合在一起,有四種情況,就是這幅圖里面的,讀讀、讀寫、寫讀和寫寫。
在數(shù)據(jù)庫里面,只有讀讀操作,不會引發(fā)數(shù)據(jù)異常,而其他三種,都會引發(fā)數(shù)據(jù)異常。這樣的總結(jié),算是一個數(shù)據(jù)異常發(fā)生的原因,但是還不是很準(zhǔn)確。
?
接下來,我們談第二個話題:MySQL的事務(wù)處理技術(shù)。主要包括事務(wù)鎖和系統(tǒng)鎖,以及事務(wù)的ACID四大特性。
MySQL/TDSQL數(shù)據(jù)庫事務(wù)處理技術(shù)概述
?
系統(tǒng)鎖是事務(wù)鎖實(shí)現(xiàn)的物理基礎(chǔ),事務(wù)鎖在系統(tǒng)鎖的基礎(chǔ)上,增加了事務(wù)相關(guān)的語義。
?
在事務(wù)鎖中,又要分為兩部分,一個是元數(shù)據(jù)鎖,如DDL操作施加的事務(wù)鎖。另外一個是我們在談及數(shù)據(jù)庫時,常常提及的鎖,其實(shí)是用戶數(shù)據(jù)上的事務(wù)鎖。前者雖然在數(shù)據(jù)庫引擎中存在,但常常被人忽略,因?yàn)槎鄶?shù)用戶關(guān)心的是用戶數(shù)據(jù)部分。
這幅圖用藍(lán)線分為兩部分,上面是元數(shù)據(jù)鎖,下面是用戶數(shù)據(jù)鎖,他們都是事務(wù)鎖。這幅圖中畫出了MySQL的重要的內(nèi)部數(shù)據(jù)結(jié)構(gòu)和他們之間的關(guān)系,大家可以按圖索驥,據(jù)此深入了解MySQL內(nèi)核實(shí)現(xiàn)事務(wù)鎖的相關(guān)技術(shù)。
在事務(wù)鎖中,所有技術(shù)的核心秘密,都在這張表里面。
例如,前面我們談到臟讀,我們看在MySQL中是怎么避免的。
Granted Mode,表示第一個事務(wù)中已經(jīng)授予的鎖,而Requested Mode表示并發(fā)的第二個事務(wù),第二個事務(wù)請求授予新的鎖如表所示。對于臟讀,第一個事務(wù)已經(jīng)授予X鎖即寫鎖,此時第二個事務(wù)申請S鎖即讀鎖,其對應(yīng)的單元中是空的表示不能授予,這樣第二個事務(wù)就被遲滯不能繼續(xù)執(zhí)行,于是就避免了臟讀現(xiàn)象。
大家可以對應(yīng)這張表,也許會考慮不可重復(fù)讀的數(shù)據(jù)異常是怎么避免的?此時,很有可能會覺得下面這張表是錯誤的。
但是,MySQL因?yàn)橛质褂昧薓VCC技術(shù)實(shí)現(xiàn)了RR即可重復(fù)讀隔離級別,所以RR的處理方式又有所不同,但這不是表明下面這張表是錯誤的。這一點(diǎn),后面會再提及。
?
數(shù)據(jù)庫的事務(wù)處理技術(shù),實(shí)現(xiàn)ACID四大特性,通常使用的技術(shù),用下面這幅腦圖可以很好的概括。
其中,一致性是目的,原子性和持久性是手段,而隔離性是在數(shù)據(jù)正確或部分正確的基礎(chǔ)上為提高數(shù)據(jù)庫性能而提出的特性。
?
MySQL的并發(fā)訪問控制技術(shù)接下來,我們談第三個話題:MySQL的并發(fā)訪問控制技術(shù)。并發(fā)訪問控制技術(shù)是數(shù)據(jù)核心技術(shù)的核心,也是數(shù)據(jù)庫中最難的技術(shù)。主要包括事務(wù)模型、ACID四大特性之間的關(guān)系、C和I特性的實(shí)現(xiàn)技術(shù)。
數(shù)據(jù)庫的事務(wù)管理器,本質(zhì)上就是一個有限狀態(tài)自動機(jī),MySQL的事務(wù)處理模塊也不另外,事務(wù)在各個狀態(tài)之間進(jìn)行流轉(zhuǎn)和切換。
?
總結(jié)MySQL的事務(wù)處理技術(shù),主要包括如下幾個方面。
?
SS2PL和MVCC都是并發(fā)訪問控制技術(shù)。對于并發(fā)訪問控制技術(shù),可以依據(jù)下圖理解,在數(shù)據(jù)庫引擎內(nèi)部,需要先在保證正確性的基礎(chǔ)上,再來提供高的性能。
?
前面,介紹過通過封鎖并發(fā)訪問控制技術(shù)怎么避免臟讀,現(xiàn)在,再分析一下MySQL、InnoDB是怎么解決幻象數(shù)據(jù)異常的。示例如圖:
MySQL對于其他隔離級別的實(shí)現(xiàn),也就是怎么避免其他數(shù)據(jù)異常現(xiàn)象,可以參考如下圖和圖中所附的鏈接,詳情在鏈接中供深入閱讀參考。
p? 序列化隔離級別:http://blog.163.com/li_hx/blog/static/1839914132017398565727/
p? 可重復(fù)讀:http://blog.163.com/li_hx/blog/static/1839914132017224904641/?suggestedreading&wumii
p? 讀已提交:http://blog.163.com/li_hx/blog/static/18399141320172198225727/?suggestedreading&wumii
p? 讀未提交:http://blog.163.com/li_hx/blog/static/18399141320172113321444/?suggestedreading&wumii
?
主流數(shù)據(jù)庫事務(wù)處理技術(shù)接下來我們談第四個話題:主流數(shù)據(jù)庫的事務(wù)處理技術(shù)。
?
可以看這張對比表格,概括了Informix、Oracle、PostgreSQL和MySQL這四個數(shù)據(jù)庫的并發(fā)控制技術(shù)。
主流的數(shù)據(jù)庫,幾乎都使用了封鎖技術(shù)和MVCC技術(shù)。只有Infomix單純地使用了封鎖技術(shù)。
Oracle盡管語法上提供了序列化隔離級別的設(shè)置,但沒有提供真正的序列化隔離級別。這是因?yàn)镺racle經(jīng)常會清理掉商在活躍的事務(wù)所需要的舊數(shù)據(jù)(以多版本形式存在的舊數(shù)據(jù))。
反倒是開源的兩個數(shù)據(jù)庫系統(tǒng),PostgreSQL和MySQL實(shí)現(xiàn)了序列化。只是MySQL是在讀數(shù)據(jù)時加鎖結(jié)合SS2PL技術(shù)實(shí)現(xiàn)了序列化,這種方式的并發(fā)度很低,性能不好。而PostgreSQL則使用SSI技術(shù)實(shí)現(xiàn)了序列化,性能相對較好。
在第一個問題中我們提出了兩種寫偏序的數(shù)據(jù)異常,PostgreSQL使用SSI技術(shù),解決了寫偏序異常。
如果從正確性和性能這兩個角度來衡量數(shù)據(jù)庫的并發(fā)控制技術(shù),顯然,PostgreSQL在理論上優(yōu)于MySQL,PostgreSQL采用的SSI技術(shù)復(fù)雜但高效。
?
這幅圖詳細(xì)對比PostgreSQL和MySQL的并發(fā)控制技術(shù)。
我們從系統(tǒng)鎖、事務(wù)鎖、事務(wù)鎖的元數(shù)據(jù)鎖和記錄元組鎖的角度進(jìn)行對比,然后再從隔離級別的角度來看這兩個數(shù)據(jù)庫的并發(fā)控制技術(shù)。
首先,PostgreSQL和MySQL都提供了系統(tǒng)鎖,也都盡量利用了底層的硬件指令如TAS指令實(shí)現(xiàn)最基本的spinlock。使用操作系統(tǒng)提供的mutex來控制共享資源的并發(fā)操作。
其次,在事務(wù)鎖方面,PostgreSQL統(tǒng)一管理元數(shù)據(jù)和用戶數(shù)據(jù),而MySQL則明顯把元數(shù)據(jù)和用戶數(shù)據(jù)分開用元數(shù)據(jù)鎖和記錄鎖進(jìn)行管理,并各自進(jìn)行了死鎖檢測。
PostgreSQL對于元組上的并發(fā)操作,加元組鎖到元組上,把事務(wù)ID記錄在元組頭上,用快照技術(shù)判斷元組的可見性,操作結(jié)束則釋放鎖。而MySQL則是用內(nèi)存鎖表記錄元組鎖,等到事務(wù)結(jié)束后才釋放。從這點(diǎn)上看,SS2PL技術(shù)的實(shí)現(xiàn),在PostgreSQL和MySQL中是不同的。
從隔離級別的角度看,PostgreSQL和MySQL都采用了MVCC技術(shù)來實(shí)現(xiàn)可重復(fù)讀和讀已提交。
PostgreSQL和MySQL在并發(fā)控制技術(shù)方面最大的差別,在于對確保數(shù)據(jù)一致性的序列化的實(shí)現(xiàn)上,采取的技術(shù)不同,理論上性能不同。這就是兩者在并發(fā)控制技術(shù)方面的最大不同之處。
?
TEG計(jì)費(fèi)平臺部研發(fā)的TDSQL,是基于MySQL的分布式數(shù)據(jù)庫,但TDSQL的做了大量的研發(fā)工作,TDSQL的技術(shù)一直在進(jìn)步,分布式事務(wù)作為數(shù)據(jù)庫里最難的問題,正在被TDSQL逐步攻克。過去的一年多,TDSQL實(shí)現(xiàn)了分布式事務(wù)的寫數(shù)據(jù)強(qiáng)一致,其原理如下:
在一個全局的事務(wù)調(diào)度器上,對于多個SET即跨SET的分布式事務(wù),TDSQL實(shí)現(xiàn)了SS2PL技術(shù)確保了數(shù)據(jù)的強(qiáng)一致性,實(shí)現(xiàn)2PC技術(shù)保證了分布式環(huán)境下事務(wù)的提交的原子性和一致性,把2PC嵌入到SS2PL整體架構(gòu)中,實(shí)現(xiàn)了分布式數(shù)據(jù)庫事務(wù)模型。Spanner等主流分布式數(shù)據(jù)庫在分布式事務(wù)處理機(jī)制上與TDSQL相似。
總結(jié)
以上是生活随笔為你收集整理的超多干货!支撑起腾讯公司计费业务的TDSQL(附PPT)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 运维总监聂鑫:腾讯海量监控体系经验分享
- 下一篇: 如何节省1T图片带宽?解密极致图像压缩!