DTCC 2023專家解讀丨GaussDB技術(shù)解讀系列之應(yīng)用無損透明(ALT)
近日,在第14屆中國數(shù)據(jù)庫技術(shù)大會(DTCC 2023)的GaussDB“五高兩易”核心技術(shù),給世界一個更優(yōu)選擇專場,華為云數(shù)據(jù)庫技術(shù)專家徐宜良分享了《GaussDB高可用之應(yīng)用無損透明》主題演講,介紹了華為云GaussDB高可用方面的最新成果。

以下為演講實錄:
大家下午好!下面由我來為大家介紹GaussDB高可用之應(yīng)用無損透明(簡稱ALT)特性。
GaussDB應(yīng)用無損透明特性簡介
我們知道用戶在使用數(shù)據(jù)庫在線業(yè)務(wù)系統(tǒng)時,如果數(shù)據(jù)庫服務(wù)端發(fā)生了維護操作,比如說重啟或者主備切換,或者發(fā)生故障時,應(yīng)用程序會感應(yīng)到數(shù)據(jù)庫之間的連接發(fā)生中斷,一些執(zhí)行的事務(wù)會被自動回滾掉。當(dāng)數(shù)據(jù)服務(wù)恢復(fù)之后,應(yīng)用程序需要重建連接,根據(jù)業(yè)務(wù)邏輯重試,這樣對業(yè)務(wù)來說不僅增加了業(yè)務(wù)系統(tǒng)的開發(fā)復(fù)雜性,也增加了業(yè)務(wù)運行風(fēng)險。
數(shù)據(jù)庫發(fā)生異常時,我們無法判斷正在執(zhí)行的事務(wù)是否提交完成。為了解決連接中斷和事務(wù)自動回滾的問題,華為云GaussDB數(shù)據(jù)庫提供了應(yīng)用無損透明的高可用能力,通過這個能力我們實現(xiàn)了連接保持和事務(wù)斷點繼續(xù)(從事務(wù)中斷的地方繼續(xù)執(zhí)行)的功能。
GaussDB應(yīng)用無損透明支持在數(shù)據(jù)庫內(nèi)部自動判斷事務(wù)邊界,緩存當(dāng)前事務(wù)執(zhí)行的會話信息和數(shù)據(jù)信息,這些信息包括會話鎖、用戶變量等內(nèi)容。在數(shù)據(jù)庫恢復(fù)時,可以根據(jù)這些緩存的會話信息和事務(wù)信息,以及服務(wù)端的日志一起自動構(gòu)建恢復(fù)出一個一致性的快照點,通過這個一致性快照點,恢復(fù)出數(shù)據(jù)庫發(fā)生主備切換那一刻所有的應(yīng)用會話和未提交的事務(wù)狀態(tài),當(dāng)會話和事務(wù)狀態(tài)都被恢復(fù)之后,我們可以從事務(wù)的一致性點上繼續(xù)往下執(zhí)行事務(wù)。
從業(yè)務(wù)視角來看,如果使用應(yīng)用無損透明功能,整個數(shù)據(jù)庫在發(fā)生主備切換期間,應(yīng)用程序只是感知到事務(wù)執(zhí)行稍微變慢了,不會感知到事務(wù)執(zhí)行中斷,也不需要進行重建連接,更不需要進行事務(wù)的重試,簡化了業(yè)務(wù)程序的開發(fā)復(fù)雜性,降低了風(fēng)險。
GaussDB應(yīng)用無損透明的架構(gòu)
我們看一下GaussDB數(shù)據(jù)庫的應(yīng)用無損透明架構(gòu)。剛才提到兩個特性,一個是連接保持,一個是事務(wù)的斷點繼續(xù)。針對連接保持,業(yè)界常用的解決方案是,在應(yīng)用程序和數(shù)據(jù)庫之間部署一個中間件,中間件對數(shù)據(jù)庫和應(yīng)用程序的連接起到轉(zhuǎn)發(fā)作用,當(dāng)數(shù)據(jù)庫服務(wù)端發(fā)生主備切換時,數(shù)據(jù)庫和中間件之間的連接斷開了,但應(yīng)用程序和中間件之間的連接沒有斷,從表現(xiàn)上看好像解決了連接保持的功能,但我們知道中間件和數(shù)據(jù)庫之間的連接還是發(fā)生了中斷,連接斷了之后會話級參數(shù)就丟失了。數(shù)據(jù)庫進行主備切換,在備庫升級為主庫的時候,所有未提交的事務(wù)自動回滾掉了。中間件是獨立的,它跟數(shù)據(jù)庫沒有任何關(guān)系,解決不了事務(wù)斷點繼續(xù)的問題,而且中間件不僅在調(diào)用鏈上多了一環(huán),增加了高可用的復(fù)雜性和風(fēng)險,還需要額外的部署,增加了資源消耗。
GaussDB數(shù)據(jù)庫沒有使用中間件方式,而是直接把能力構(gòu)建在驅(qū)動層。當(dāng)數(shù)據(jù)庫服務(wù)端主備切換或者發(fā)生故障時,驅(qū)動層不會把中斷信息上報到應(yīng)用程序,而是在自己內(nèi)部進行連接保持,保持的時候緩存了會話數(shù)據(jù)和事務(wù)數(shù)據(jù)。當(dāng)數(shù)據(jù)庫服務(wù)端恢復(fù)之后,驅(qū)動會自動建立一個新的會話連接,利用緩存的會話數(shù)據(jù),恢復(fù)原來連接上會話級的參數(shù)。會話級參數(shù)恢復(fù)之后,根據(jù)緩存的事務(wù)信息繼續(xù)恢復(fù)原來未提交的事務(wù)狀態(tài),這樣會話和事務(wù)狀態(tài)都恢復(fù)之后,事務(wù)可以從它主備切換時的一致性快照點繼續(xù)執(zhí)行。

剛才提到主庫宕機備庫升主之后,一般數(shù)據(jù)庫會把未提交的事務(wù)回滾掉,針對這種未提交事務(wù)的回滾問題,GaussDB在啟動應(yīng)用無損透明功能之后,未提交的事務(wù)不能自動回滾,需要保持未提交事務(wù)的狀態(tài),等待新建的連接過來之后進行事務(wù)的恢復(fù)和橋接事務(wù)。這個地方我們引用了邏輯事務(wù)ID的功能,通過邏輯事務(wù)ID和真實的事務(wù)ID匹配,去判斷事務(wù)的狀態(tài)有效性。如果事務(wù)狀態(tài)是有效的,就會把事務(wù)信息綁定到連接上,實現(xiàn)數(shù)據(jù)庫備庫升主庫之后未提交事務(wù)狀態(tài)的恢復(fù)。
當(dāng)數(shù)據(jù)庫發(fā)生主備切換時,連接發(fā)生中斷,應(yīng)用程序也不知道數(shù)據(jù)庫發(fā)生了什么,也不知道數(shù)據(jù)庫什么時候恢復(fù)。這時,一般的策略會采用定時的重試,不停地去連接,查看數(shù)據(jù)庫是否正常。這種定時嘗試機制存在兩個問題:一是數(shù)據(jù)庫服務(wù)正在恢復(fù)期間,不停的嘗試會導(dǎo)致不斷的報錯,是無效且多余的操作;二是定時檢測機制存在延時問題,當(dāng)數(shù)據(jù)庫服務(wù)恢復(fù)后,應(yīng)用無法實時感知到服務(wù)是否恢復(fù)。
GaussDB 提供了一種實時消息通知服務(wù)(即GNS),當(dāng)數(shù)據(jù)庫服務(wù)端狀態(tài)發(fā)生任何變化的時候,它可以及時發(fā)送消息給應(yīng)用程序,應(yīng)用程序收到后可以進行相應(yīng)的動作。GaussDB消息通知服務(wù)是一種實時的主動推送的方式,時延更低,消耗資源更少。
GaussDB應(yīng)用無損透明的使用方式
說到應(yīng)用無損透明,其使用方式非常簡單,只需要在應(yīng)用程序向數(shù)據(jù)庫建立連接時打開功能開關(guān)即可。以JDBC驅(qū)動為例,當(dāng)應(yīng)用程序想使用應(yīng)用無損透明功能時,只需要在JDBC的URL中配置GaussDB消息通知服務(wù)的IP地址和端口即可。這時會有一個情況,一個數(shù)據(jù)庫集群有很多應(yīng)用程序客戶端,有的應(yīng)用客戶端想用應(yīng)用無損透明功能,有的不用,打開或關(guān)閉應(yīng)用無損透明功能這兩種情況同時存在。那么當(dāng)數(shù)據(jù)庫發(fā)生主備切換時,使用應(yīng)用無損透明功能的應(yīng)用程序客戶端,就會具備連接保持和事務(wù)斷點繼續(xù)的能力,這個時候的數(shù)據(jù)庫主備切換操作對業(yè)務(wù)來說是無感知的。沒有配置使用應(yīng)用無損透明功能的應(yīng)用程序客戶端,當(dāng)數(shù)據(jù)庫發(fā)生主備切換或者異常時,可以立即感知到連接中斷,數(shù)據(jù)庫正在執(zhí)行的事務(wù)會立即回滾掉。
此外,我們看到GNS是對等多活的,當(dāng)客戶端很多時,可以連接到不同的GNS,相當(dāng)于負(fù)載均衡的功能,而不是像主備方式那樣,把所有的資源壓在一臺物理機上。

GaussDB應(yīng)用無損透明的使用場景
剛才介紹了一下GaussDB應(yīng)用無損透明架構(gòu)的原理和使用方法,下面介紹其使用場景,主要包括計劃內(nèi)主備切換、計劃外主備切換、容災(zāi)切換三個方面。
計劃內(nèi)主備切換
計劃內(nèi)主備切換一般都是數(shù)據(jù)庫在進行例行的維護和升級中用到的,由運維管理員主動發(fā)起。在做計劃內(nèi)主備切換時,GaussDB會自動判斷和等待達到一個安全的事務(wù)邊界后,在驅(qū)動層緩存會話數(shù)據(jù)和事務(wù)數(shù)據(jù),把數(shù)據(jù)緩存完之后數(shù)據(jù)庫再進行主備切換。
安全的事務(wù)邊界是指當(dāng)前會話上的事務(wù)執(zhí)行到某一個一致性點,可以分為兩種情況,一是執(zhí)行完事務(wù)后進行主備切換,即事務(wù)級排空,二是執(zhí)行完一個SQL語句即可進行主備切換,即語句級排空,這個時候事務(wù)屬于未提交狀態(tài),可以說語句級排空對業(yè)務(wù)影響更小一點。
在整個數(shù)據(jù)庫主備切換期間,GaussDB驅(qū)動進行連接保持,當(dāng)數(shù)據(jù)庫服務(wù)恢復(fù)之后,先重建連接,再去恢復(fù)事務(wù),事務(wù)恢復(fù)之后從事務(wù)一致性點繼續(xù)執(zhí)行。我們可以看到在正常的計劃內(nèi)主備切換場景下,使用應(yīng)用無損透明特性,對數(shù)據(jù)庫來說是無感知的,而且這種主備切換會使用語句級排空。OLTP場景下,SQL語句執(zhí)行時長都是毫秒級的,使用應(yīng)用無損透明功能下的主備切換只是增加了一個SQL語句執(zhí)行時間的等待,也就是多等待一個毫秒級的時間,相對于原來幾秒甚至幾十秒的主備切換時間來說,多出來的毫秒級等待時間幾乎可以忽略不計。
計劃外主備切換
下面我們看一下計劃外的場景。計劃外可以說是災(zāi)難性的、突發(fā)的,它和計劃內(nèi)的主備切換場景的部分處理機制有所不同。針對計劃外的主備切換,GaussDB數(shù)據(jù)庫通過基于事務(wù)粒度來緩存整個事務(wù)里的語句和重放整個事務(wù)來實現(xiàn)。GaussDB自動以事務(wù)作為一致性邊界,在事務(wù)執(zhí)行過程中,驅(qū)動自動緩存執(zhí)行過的事務(wù)SQL語句。數(shù)據(jù)庫服務(wù)恢復(fù)后,GaussDB重新執(zhí)行緩存的事務(wù)SQL語句,為了避免重復(fù)執(zhí)行和提交事務(wù),驅(qū)動重放時會首先根據(jù)邏輯事務(wù)ID來查詢事務(wù)執(zhí)行狀態(tài),如果事務(wù)已經(jīng)提交了就不需要再執(zhí)行。
之所以采用事務(wù)粒度重放,而不是以語句粒度重放,是因為數(shù)據(jù)庫的主庫和備庫之間的數(shù)據(jù)同步,是以事務(wù)為單位的,當(dāng)事務(wù)在主庫上被提交了,為了保證數(shù)據(jù)不丟失,一定會把事務(wù)的WAL日志實時同步到備庫上。這是數(shù)據(jù)庫的主備數(shù)據(jù)復(fù)制的一個通用的基本機制,已經(jīng)完全能滿足事務(wù)粒度重放的要求。而如果要使用語句粒度的重放,必然需要采用一些額外的手段,例如使用savepoint作為主備實時同步邊界,用來階段性保存進度等。和事務(wù)粒度重放相比,語句粒度重放使方案更復(fù)雜,覆蓋的場景更少,性能更差。
容災(zāi)切換
我們看一下容災(zāi)場景。異地容災(zāi)是兩個城市相距幾千公里,時延在幾十毫秒,這么大的時延很難要求跨地區(qū)訪問數(shù)據(jù)庫,所以異地場景的容災(zāi)切換是數(shù)據(jù)庫的容災(zāi)和業(yè)務(wù)程序容災(zāi)相互配合,同時切換的過程。目前容災(zāi)切換面臨一個困境,因為這兩個切換是互相獨立的,數(shù)據(jù)庫集群切換完了,而應(yīng)用程序卻沒有切換完,端到端看數(shù)據(jù)庫恢復(fù)了,但是業(yè)務(wù)沒有恢復(fù)。
為了解決端到端的問題,GaussDB提供了一個消息通知服務(wù)功能(即GNS)。當(dāng)數(shù)據(jù)庫發(fā)生容災(zāi)切換時,比如說生產(chǎn)集群降為災(zāi)備集群時,會立即把消息發(fā)送到應(yīng)用,應(yīng)用程序收到數(shù)據(jù)庫集群降備的事件通知后,就可以立即進行主備切換;當(dāng)數(shù)據(jù)庫容災(zāi)集群升為主集群時,GNS會及時通知應(yīng)用程序,應(yīng)用程序收到消息之后,就可以立即切流以恢復(fù)業(yè)務(wù)。這樣一個相互配合的機制,可以解決端到端的RTO時長問題,不需要多余的等待,也不需要人為判斷。
除了異地容災(zāi)外,還有一種同城容災(zāi)部署場景,因為是同城,所以時延比較低,網(wǎng)絡(luò)環(huán)境比較好。同城容災(zāi)這種場景下,可能只是數(shù)據(jù)庫集群發(fā)生切換,而應(yīng)用程序保持不變。這種場景如果我們使用GaussDB提供的應(yīng)用無損透明機制,也就是通過連接保持和事務(wù)斷點繼續(xù)技術(shù),在同城容災(zāi)切換時,不僅能確保RPO=0不丟數(shù)據(jù),還能保證數(shù)據(jù)庫的容災(zāi)切換對應(yīng)用程序也是透明的。
今天我分享的內(nèi)容就到這里,感謝大家。