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