数据库表的软硬关联_数据库容灾能力的探讨(一)
在過(guò)去十多年在Oracle,騰訊等公司的數(shù)據(jù)庫(kù)系統(tǒng)內(nèi)核開(kāi)發(fā)工作中,我的大量工作就是確保數(shù)據(jù)庫(kù)系統(tǒng)在各種環(huán)境故障情況下,能夠保持?jǐn)?shù)據(jù)一致性和持續(xù)可用地提供數(shù)據(jù)讀寫(xiě)服務(wù)。這些工作既包括在騰訊參與開(kāi)發(fā)的TDSQL 分布式數(shù)據(jù)庫(kù),也包括過(guò)去的近一年我開(kāi)發(fā)的昆侖分布式數(shù)據(jù)庫(kù)。
過(guò)去3個(gè)多月我花了大量時(shí)間精力解決了昆侖數(shù)據(jù)庫(kù)使用的存儲(chǔ)節(jié)點(diǎn)的容災(zāi)問(wèn)題。昆侖分布式數(shù)據(jù)庫(kù)使用我改進(jìn)后的Percona-MySQL-8.0.18-9,我將它命名為Kunlun-Percona-MySQL-8.0.18-9。官方版本的Percona-MySQL-8.0.18-9的group replication和分布式事務(wù)處理(即XA)有很多個(gè)容災(zāi)能力方面的缺陷,這些缺陷有一些是在mysql-5.7時(shí)代就已經(jīng)存在的了---當(dāng)時(shí)我在騰訊做TDSQL分布式事務(wù)處理功能開(kāi)發(fā)的時(shí)候修復(fù)了這些bug并報(bào)告給了mysql官方團(tuán)隊(duì)。很遺憾mysql官方并沒(méi)有修復(fù)全部的這些bug,多數(shù)關(guān)鍵的bug仍然在mysql8.0存在,盡管我在每個(gè)bug報(bào)告中都提供了我的patch。
在Kunlun-Percona-MySQL-8.0.18-9中,我的改進(jìn)填補(bǔ)了MGR在處理XA事務(wù)方面的諸多缺陷和空白。在本文中,我希望基于過(guò)往工作歷程中積累的經(jīng)驗(yàn),給讀者分享一下我對(duì)分布式數(shù)據(jù)庫(kù)系統(tǒng)的容災(zāi)能力和需求的理解,并介紹Kunlun-Percona-MySQL-8.0.18-9修復(fù)的容災(zāi)缺陷。
本文內(nèi)容包括數(shù)據(jù)庫(kù)系統(tǒng)需要應(yīng)對(duì)的故障(即災(zāi)難)類(lèi)型和環(huán)境可靠性模型,災(zāi)難可能造成的損害,以及容災(zāi)的方法和手段,包括數(shù)據(jù)庫(kù)事務(wù)處理,數(shù)據(jù)備份和恢復(fù),數(shù)據(jù)復(fù)制與高可用性,兩階段提交和分布式事務(wù)處理等數(shù)據(jù)庫(kù)容災(zāi)相關(guān)的內(nèi)容。
本文不含蓋或者針對(duì)特定的數(shù)據(jù)模型(比如關(guān)系模型)和查詢(xún)語(yǔ)言(比如SQL),因此本文內(nèi)容對(duì)于關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng),json/xml 數(shù)據(jù)庫(kù)管理系統(tǒng),對(duì)象數(shù)據(jù)庫(kù)管理系統(tǒng),key-value數(shù)據(jù)庫(kù)管理系統(tǒng)和圖數(shù)據(jù)庫(kù)管理系統(tǒng)都適用。
分布式數(shù)據(jù)庫(kù)系統(tǒng)的環(huán)境可靠性模型
生產(chǎn)中運(yùn)行的分布式數(shù)據(jù)庫(kù)集群通常由運(yùn)行在一個(gè)或者多個(gè)數(shù)據(jù)中心的計(jì)算機(jī)服務(wù)器聯(lián)網(wǎng)構(gòu)成,這些計(jì)算機(jī)服務(wù)器硬件以及網(wǎng)絡(luò),以及硬件和網(wǎng)絡(luò)中運(yùn)行的軟件,以及操作所有這些軟硬件的人員執(zhí)行的操作和行為,就是分布式數(shù)據(jù)庫(kù)集群運(yùn)行的環(huán)境。這個(gè)環(huán)境可能出現(xiàn)的錯(cuò)誤和故障就是分布式數(shù)據(jù)庫(kù)系統(tǒng)需要處理的故障來(lái)源。
集群中任何節(jié)點(diǎn)的軟硬件故障,或者任何節(jié)點(diǎn)之間的網(wǎng)絡(luò)連接故障,都可能影響集群的正常工作。由于其天然的復(fù)雜性,這個(gè)環(huán)境發(fā)生故障的幾率并不低,因此分布式數(shù)據(jù)庫(kù)系統(tǒng)需要將節(jié)點(diǎn)軟硬件故障和網(wǎng)絡(luò)故障當(dāng)作常見(jiàn)情況來(lái)處理,而不是當(dāng)作極低概率的事件來(lái)處理。
分布式數(shù)據(jù)庫(kù)集群需要處理的軟件環(huán)境故障包括計(jì)算機(jī)服務(wù)器的操作系統(tǒng)自身的bug導(dǎo)致的工作故障和系統(tǒng)管理員人為錯(cuò)誤導(dǎo)致的運(yùn)行錯(cuò)誤等,還包括網(wǎng)絡(luò)節(jié)點(diǎn)的控制軟件自身的bug以及網(wǎng)絡(luò)管理員人為錯(cuò)誤導(dǎo)致的網(wǎng)絡(luò)連接故障,以及數(shù)據(jù)庫(kù)操作人員使用和管理分布式數(shù)據(jù)庫(kù)集群時(shí)誤操作導(dǎo)致的分布式數(shù)據(jù)庫(kù)集群節(jié)點(diǎn)故障等,比如誤殺進(jìn)程,誤刪數(shù)據(jù)文件等;需要處理的硬件環(huán)境故障包括服務(wù)器或者網(wǎng)絡(luò)設(shè)備短暫斷電,服務(wù)器的持久存儲(chǔ)設(shè)備損壞,服務(wù)器短暫重啟,服務(wù)器硬件永久損壞或者停止工作,以及部分或者全部網(wǎng)絡(luò)連接短暫失效和長(zhǎng)期失效等。
容災(zāi)能力對(duì)于一個(gè)數(shù)據(jù)庫(kù)系統(tǒng)來(lái)說(shuō)是非常關(guān)鍵的能力,特別是對(duì)于分布式數(shù)據(jù)庫(kù)集群來(lái)說(shuō),其多節(jié)點(diǎn)的架構(gòu)導(dǎo)致構(gòu)成集群的軟硬件和網(wǎng)絡(luò)發(fā)生故障的幾率更高,因此必須有絕對(duì)可靠的容災(zāi)能力,確保在任何節(jié)點(diǎn)發(fā)生軟硬件故障情況下都不會(huì)導(dǎo)致數(shù)據(jù)一致性問(wèn)題,或者丟失已提交的事務(wù)的改動(dòng),或者導(dǎo)致系統(tǒng)不可用。為了展現(xiàn)不同規(guī)模的分布式數(shù)據(jù)庫(kù)集群環(huán)境故障幾率,下面我們就量化上述故障的概率。
首選我們定義分布式數(shù)據(jù)庫(kù)的‘集群環(huán)境可靠性’為組成該集群的軟硬件節(jié)點(diǎn)及其間的網(wǎng)絡(luò)連接都不發(fā)生故障的概率。然后我們計(jì)算在不同的集群規(guī)模和軟硬件預(yù)期可靠性情況下這個(gè)‘集群環(huán)境可靠性’的值。
以昆侖分布式數(shù)據(jù)庫(kù)集群或者TDSQL分布式數(shù)據(jù)庫(kù)集群為例,假設(shè)集群有 N個(gè)存儲(chǔ)shard,每個(gè)shard一主兩備,同時(shí)還有N個(gè)計(jì)算節(jié)點(diǎn)與每個(gè)shard的主節(jié)點(diǎn)相連接。每個(gè)存儲(chǔ)和計(jì)算節(jié)點(diǎn)運(yùn)行在獨(dú)立的硬件計(jì)算機(jī)上面;同時(shí)這些節(jié)點(diǎn)之間還有至少2*N+N*N條網(wǎng)絡(luò)連接(不考慮讀備機(jī)的情況下)。這樣一共有N*N+6*N 個(gè)可能發(fā)生故障的點(diǎn)。我們假設(shè)每個(gè)點(diǎn)在一定時(shí)間范圍內(nèi),比如1個(gè)月內(nèi),可以以一個(gè)穩(wěn)定的概率保持正常工作。在這個(gè)時(shí)間范圍內(nèi)只要集群中有1個(gè)節(jié)點(diǎn)發(fā)生了故障,就認(rèn)定集群環(huán)境就發(fā)生了故障。這樣就可以計(jì)算在一定時(shí)間范圍內(nèi)集群環(huán)境的可靠性概率。表1顯示了在不同的N和單個(gè)點(diǎn)可靠性情況下‘集群環(huán)境可靠性’。
從這個(gè)表中可以看出,對(duì)于一個(gè)分布式數(shù)據(jù)庫(kù)集群來(lái)說(shuō),在時(shí)間足夠長(zhǎng)(比如一年),范圍足夠廣(比如有多個(gè)集群)的情況下,某個(gè)集群環(huán)境出現(xiàn)故障的幾率很大,隨著時(shí)間不斷增長(zhǎng),這個(gè)概率是趨近100%的。假如分布式數(shù)據(jù)庫(kù)集群沒(méi)有滴水不漏的毫無(wú)破綻的容災(zāi)能力的話(huà),那么在實(shí)際生產(chǎn)中分布式數(shù)據(jù)庫(kù)集群長(zhǎng)期不出現(xiàn)系統(tǒng)故障或者數(shù)據(jù)一致性錯(cuò)誤幾乎是不可能的。
不同的分布式數(shù)據(jù)庫(kù)集群的總可能故障點(diǎn)數(shù)計(jì)算方法未必完全相同,但是肯定時(shí)隨著N的增加而增加的,集群環(huán)境可靠性隨著時(shí)間的增長(zhǎng)以及N的增大而降低也是必然的,因此無(wú)論對(duì)于哪一種分布式數(shù)據(jù)庫(kù),都會(huì)有類(lèi)似的結(jié)論。可見(jiàn)分布式數(shù)據(jù)庫(kù)集群必須具備完備的堅(jiān)不可摧的容災(zāi)能力,否則一定會(huì)出現(xiàn)數(shù)據(jù)不一致,數(shù)據(jù)損壞丟失或者數(shù)據(jù)庫(kù)服務(wù)停止等嚴(yán)重的問(wèn)題。
另外想提一下,上面的統(tǒng)計(jì)雖然用昆侖分布式數(shù)據(jù)庫(kù)和TDSQL做比較,但事實(shí)上對(duì)于TDSQL分布式數(shù)據(jù)庫(kù)集群來(lái)說(shuō),集群還需要一個(gè)zookeeper集群來(lái)存儲(chǔ)集群關(guān)鍵元數(shù)據(jù),而且通常這個(gè)zookeeper集群會(huì)有多個(gè)TDSQL集群共享。zookeeper集群軟硬件和網(wǎng)絡(luò)也是一組可能的故障來(lái)源,并且一旦故障會(huì)導(dǎo)致所有使用該zookeeper集群的TDSQL集群不能正常工作,甚至發(fā)生數(shù)據(jù)一致性錯(cuò)誤或者丟失已提交的事務(wù)。但是上述環(huán)境可靠性概率計(jì)算并沒(méi)有考慮zookeeper集群的故障可能性,否則其值會(huì)更快趨近于0。所以zookeeper也必須要有非常可靠的容災(zāi)能力才行。
下面我們回顧一下數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)發(fā)展的50多年以來(lái),在不同的發(fā)展階段所面臨的災(zāi)難或者故障類(lèi)型,故障的可能損害以及故障處理的方法。
不同時(shí)代的數(shù)據(jù)庫(kù)管理系統(tǒng)面對(duì)的災(zāi)難的范圍和容災(zāi)需求
經(jīng)典數(shù)據(jù)庫(kù)時(shí)代(單機(jī))
單機(jī)數(shù)據(jù)庫(kù)時(shí)代,DBMS實(shí)現(xiàn)了單機(jī)數(shù)據(jù)庫(kù)事務(wù)處理,和單機(jī)事務(wù)的ACID保障。不過(guò)一旦數(shù)據(jù)庫(kù)服務(wù)器故障,則數(shù)據(jù)庫(kù)服務(wù)會(huì)停止,直到故障被排除,數(shù)據(jù)庫(kù)服務(wù)器重新啟動(dòng)。
需要應(yīng)對(duì)的災(zāi)難
硬件故障:
1. 數(shù)據(jù)庫(kù)服務(wù)器硬件部件損壞;
2. 服務(wù)器斷電或者其他原因?qū)е路?wù)器在數(shù)據(jù)庫(kù)服務(wù)器運(yùn)行期間退出
3. 數(shù)據(jù)文件所在的存儲(chǔ)介質(zhì)損壞或丟失
軟件故障:
1. 操作系統(tǒng)bug或者人為錯(cuò)誤導(dǎo)致操作系統(tǒng)異常退出,或者系統(tǒng)調(diào)用失敗
2. 軟件bug或者人為錯(cuò)誤導(dǎo)致DBMS進(jìn)程異常退出(也就是DBMS進(jìn)程crash,被kill掉等情況)
3. 寫(xiě)入存儲(chǔ)介質(zhì)或者從其中讀出的頁(yè)面數(shù)據(jù)錯(cuò)誤
可能產(chǎn)生的錯(cuò)誤
1. 已提交的事務(wù)的數(shù)據(jù)或者修改丟失
2. 數(shù)據(jù)庫(kù)系統(tǒng)的數(shù)據(jù)文件不可用導(dǎo)致數(shù)據(jù)全部或者部分丟失
3. 沒(méi)有直接修改DBMS的數(shù)據(jù)文件的情況下,其數(shù)據(jù)文件的內(nèi)容損壞導(dǎo)致無(wú)法被 數(shù)據(jù)庫(kù)服務(wù)器程序使用,從而丟失部分或者全部數(shù)據(jù)
對(duì)容災(zāi)能力的要求
1.如果存儲(chǔ)介質(zhì)未損壞,那么數(shù)據(jù)庫(kù)服務(wù)器進(jìn)程可以正常重新啟動(dòng),并且重新啟動(dòng)后,所有已提交的事務(wù)的修改不丟失(durability),可以正常使用。
2.能夠確保DBMS不會(huì)在任何情況下?lián)p壞其數(shù)據(jù)文件(首選),或者損壞后可以完全修復(fù)(比如mysql myisam引擎的repair工具)其數(shù)據(jù)文件。
3.能夠發(fā)現(xiàn)數(shù)據(jù)文件頁(yè)面的發(fā)生的數(shù)據(jù)錯(cuò)誤并報(bào)告給數(shù)據(jù)庫(kù)管理員,以便DBA使用備份的數(shù)據(jù)來(lái)恢復(fù)數(shù)據(jù)文件到最新備份的版本。
容災(zāi)能力的實(shí)現(xiàn)方法
單機(jī)數(shù)據(jù)庫(kù)實(shí)現(xiàn)容災(zāi)能力最重要的方法就是經(jīng)典的數(shù)據(jù)庫(kù)事務(wù)處理技術(shù),也就是write ahead logging(WAL)。通過(guò)為每個(gè)事務(wù)記錄redo log和undo log,在數(shù)據(jù)庫(kù)服務(wù)器啟動(dòng)時(shí)使用redo log做事務(wù)恢復(fù),使用undo log回滾掉未提交的事務(wù)。刷任何數(shù)據(jù)頁(yè)面P到數(shù)據(jù)文件之前必須將記錄了修改這個(gè)頁(yè)面的redo日志R先刷到事務(wù)日志文件。并且日志R與頁(yè)面P通過(guò)P頭部的lsn關(guān)聯(lián)起來(lái),即P.lsn = R.lsn,這樣恢復(fù)機(jī)制就可以把每一個(gè)數(shù)據(jù)頁(yè)面恢復(fù)到系統(tǒng)上次退出前最后一次刷redo log時(shí)的狀態(tài)。 同時(shí),在回滾段中記錄每個(gè)修改了的數(shù)據(jù)行的前鏡像變動(dòng)(before image delta),也就是使用當(dāng)前行數(shù)據(jù)得到修改之前的行數(shù)據(jù)的變化。這樣數(shù)據(jù)庫(kù)恢復(fù)機(jī)制就可以恢復(fù)已提交的事務(wù),并回滾問(wèn)提交的事務(wù)。
為了應(yīng)對(duì)存儲(chǔ)介質(zhì)損壞和丟失,以及數(shù)據(jù)文件頁(yè)面發(fā)生數(shù)據(jù)錯(cuò)誤,DBMS需要發(fā)現(xiàn)并報(bào)告這樣的數(shù)據(jù)錯(cuò)誤,以便DBA使用最新的全量備份和增量備份恢復(fù)到最新備份的一致的數(shù)據(jù)版本。
單機(jī)數(shù)據(jù)庫(kù)時(shí)代一旦服務(wù)器軟硬件故障則數(shù)據(jù)庫(kù)服務(wù)就會(huì)在一段時(shí)間內(nèi)不可用。為了解決這個(gè)問(wèn)題,在上世紀(jì)90年代開(kāi)始業(yè)界逐步進(jìn)入了高可用(high availability, HA) 時(shí)代。通過(guò)建立主備節(jié)點(diǎn)集群,從主節(jié)點(diǎn)持續(xù)傳輸對(duì)數(shù)據(jù)的增刪改操作數(shù)據(jù)到備機(jī)節(jié)點(diǎn)并在備機(jī)實(shí)施這些操作,就可以將同樣的數(shù)據(jù)存儲(chǔ)多個(gè)copy到多個(gè)備機(jī)節(jié)點(diǎn)上面。一旦主節(jié)點(diǎn)發(fā)生故障無(wú)法工作,具備HA 能力的DBMS可以自動(dòng)發(fā)現(xiàn)主節(jié)點(diǎn)故障并把合適的備機(jī)節(jié)點(diǎn)升級(jí)為新的主節(jié)點(diǎn),從而不間斷數(shù)據(jù)讀寫(xiě)服務(wù)。
不過(guò)HA時(shí)代由于引入了更多的計(jì)算機(jī)服務(wù)器和網(wǎng)絡(luò)來(lái)構(gòu)成集群,因而可能出現(xiàn)故障的點(diǎn)也更多了,也就需要處理更多的故障情形。
(未完待續(xù))
總結(jié)
以上是生活随笔為你收集整理的数据库表的软硬关联_数据库容灾能力的探讨(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python把数据写入excel_Pyt
- 下一篇: 基金认购超额等比例分配 新基金投资注意