openGauss資料庫原始碼解析系列文章——備份恢復機制:openGauss全量備份技術

語言: CN / TW / HK

目錄

10.1  openGauss全量備份技術

10.1.1  gs_basebackup備份工具

10.1.2  gs_basebackup備份互動流程


 

本文主要介紹openGauss的備份恢復原理和技術。備份恢復是資料庫日常維護的一個例行活動,通過把資料庫資料備份到另外一個地方,可以抵禦介質類的損壞,增加資料庫資料的可靠性。資料庫的備份恢復主要分為邏輯備份恢復和物理備份恢復。

邏輯備份是把資料庫中的資料匯出為文字檔案,這些文字檔案內容一般來說是SQL語句。恢復資料時再把文字檔案中的SQL語句匯入資料庫中恢復。邏輯備份比較靈活,可以支援庫級、模式級和表級備份,但邏輯備份只讀取了某個時間點的資料庫快照對應的資料,很難實現增量備份,恢復時也無法恢復到指定的時間點。在openGauss中實現邏輯備份恢復的工具為gs_dump/gs_restore,具體使用方法參考openGauss官網《管理員指南》手冊。

物理備份是直接複製資料庫的物理檔案,效能比較高,對應用的約束比較少,但只能對整個庫進行備份。物理備份又分為全量備份和增量備份。增量備份又有兩種方式,一種是結合資料庫的髒頁跟蹤實現的增量備份,另外一種是根據redo日誌的增量實現的增量備份。根據髒頁進行的增量備份可以和歷史上的備份進行合併,減少儲存空間的佔用,恢復時可以恢復到增量備份的時間點,無法恢復到任意時間點。根據redo日誌進行的增量備份在恢復時可以恢復到指定時間點,但所有的redo日誌都需要進行備份,佔用的儲存空間較大。

邏輯備份主要用於異構資料庫的遷移,物理備份主要用於保障資料庫資料的可靠性。本章主要介紹openGauss的物理備份機制,包括全量備份技術和增量備份技術。

10.1  openGauss全量備份技術

openGauss有兩個備份工具gs_basebackup和gs_probackup。gs_basebackup只能進行全量備份,gs_probackup既可進行全量備份,也可進行增量備份。gs_probackup全量備份的原理和gs_basebackup是類似的,本節以gs_basebackup工具為例介紹全量備份的原理。

10.1.1  gs_basebackup備份工具

gs_basebackup是一個獨立的二進位制程式,有自己的主函式,程式碼在src/bin/pg_basebackup目錄下。在備份時,gs_basebackup通過指定的IP地址連線openGauss資料庫伺服器,openGauss資料庫伺服器把需要備份的資料檔案和redo日誌檔案傳送給備份工具gs_basebackup,gs_basebackup收到後把檔案存放到本地指定的目錄,從而完成資料庫的備份。

gs_basebackup主要有兩種備份格式:plain普通格式和tar壓縮包格式。普通格式就是以通常的資料檔案進行備份,tar壓縮包格式就是把備份檔案打包進行備份。openGauss的tar包頭是2048位元組,檔名最長支援1024個位元組長度,不是標準的tar,所以需要openGauss自己解包,實現解包的命令為GsTar。

gs_basebackup的主幹處理流程比較簡單,首先對支援的命令列引數進行解析,主要的命令列引數請參照表1。引數解析後進入備份主函式BaseBackup,BaseBackup參照後面詳細介紹。在主函式之後是free_basebackup,釋放前面分配的記憶體資源,整個備份流程就結束了。

表1  命令引數

引數

描述

-D

備份的目的路徑

-F

備份的檔案格式,plain普通格式和tar壓縮包格式

-X

是否進行流複製模式,當前要求必須採用流複製模式,保證備份資料的正確性

-Z

壓縮級別

-c

備份時是否做快速檢查點

-h

進行備份的資料庫伺服器監聽IP地址

-p

進行備份的資料庫伺服器監聽埠號

-U

進行備份時連線資料庫伺服器的使用者名稱

-W

進行備份時連線資料庫伺服器的密碼

-s

備份時狀態更新時間間隔

-v

是否顯示備份詳細資訊

- P

是否顯示備份進度資訊

10.1.2  gs_basebackup備份互動流程

1. plain普通格式備份

普通格式備份的主函式為BaseBackup,具體互動流程如圖1所示。

圖1 備份互動流程

從圖1可以看出,資料庫物理全量備份主要包括兩個流程,一個是資料檔案的備份,一個是XLOG檔案的備份。詳細過程如下。

(1) gs_basebackup在BaseBackup函式中建立資料傳輸的連線。

(2) 執行IDENTIFY_SYSTEM命令,獲取時間線和系統識別符號。

(3) 執行BASE_BACKUP LABEL備份命令,獲取XLOG的存放路徑和備份開始時日誌的位置。然後從資料庫伺服器獲取表空間的路徑,建立對應的路徑。

(4) 在拷貝資料檔案之前,建立一個單獨的子程序用於日誌傳輸。日誌傳輸處理的主函式為StartLogStreamer,在StartLogStreamer函式中,先呼叫GetConnection函式建立一個日誌傳輸的連線,然後呼叫fork函式建立子程序,在子程序內部通過LogStreamerMain函式呼叫ReceiveXlogStream執行實際的日誌傳輸。在ReceiveXlogStream中,也是先呼叫IDENTIFY_SYSTEM獲取系統標識並且進行校驗和前面獲取的系統標識是否一致。接著執行START_REPLICATION,通知資料庫伺服器日誌傳輸的起始位置。呼叫createHeartbeatTimer啟動心跳執行緒,保證能夠實時監控傳輸過程中的連線狀態。接下來進行日誌接收迴圈,接收資料庫伺服器傳輸的日誌,寫入本地日誌路徑,直到接收到通知的日誌停止位置。

(5) 在主程序建立日誌接收子程序之後,呼叫ReceiveAndUnpackTarFile進行資料檔案的拷貝,在這個函式中,有一個while (1)迴圈,迴圈接收資料庫伺服器傳輸的資料檔案,直到接收完資料庫服務傳輸的全部資料檔案。資料庫檔案傳輸完畢後,資料庫伺服器會返回一個備份結束時的日誌位置。

(6) 主程序接收這個位置,把這個位置通過管道傳送給日誌接收子程序,日誌接收子程序把這個位置與當前日誌傳輸位置相比較,如果達到了這個位置,則日誌接收結束,日誌子程序退出。主程序等到日誌傳輸子程序退出後,資料庫備份的主流程就基本結束了。這個過程保證了redo日誌覆蓋到整個資料庫檔案的複製過程,即使在複製資料檔案時可能由於資料庫的併發刷盤導致資料頁可能不一致,但這些不一致可以通過redo日誌進行恢復,從而保證整個資料庫備份資料的一致性。

(7) 後面兩個函式,一個是FetchMotCheckpoint函式,這個函式備份MOT記憶體表的資料檔案,流程和前面基本相似;還有一個是backup_dw_file函式,在backup_dw_file檔案中,刪除存在的雙寫檔案,然後寫入一個空的資料頁,這個只是一個空檔案,避免啟動時的檔案檢查異常。最後釋放前面獲得的系統識別符號,至此,客戶端工具完成整個備份流程。

在資料庫伺服器端,備份主要在HandleWalReplicationCommand函式中進行,該函式主要接收客戶端命令,並根據命令識別符號進行處理。

(1) IDENTIFY_SYSTEM命令對應的識別符號為T_IdentifySystemCmd,處理函式為IdentifySystem,在IdentifySystem中,構造systemid和timeline的資料元組,返回給客戶端備份工具。

(2) BASE_BACKUP LABEL命令對應的識別符號為T_BaseBackupCmd,對應的主要處理函式為SendBaseBackup,在SendBaseBackup函式中,首先呼叫parse_basebackup_options解析備份的命令引數,包括備份標籤(label)、備份進度(progress)、快速檢查點(fast)、是否等待(nowait)、是否包括redo日誌(wal)等選項引數,最後呼叫send_xlog_location函式傳送日誌檔案的路徑,接著呼叫perform_base_backup函式執行資料檔案的備份。在perform_base_backup函式中,首先呼叫do_pg_start_backup執行備份許可權檢查,根據備份命令列引數決定是否請求檢查點(RequestCheckpoint函式),然後生成備份標籤檔案backup_label,backup_label是備份的重要檔案,這個檔案包括的內容如下。

① START WAL LOCATION:備份開始時日誌的位置。

② CHECKPOINT LOCATION:檢查點的位置。

③ BACKUP METHOD:備份方法,pg_start_backup方式還是streamed方式。pg_start_backup沒有指定備份標籤檔案,整個資料庫只能同時執行一個備份。streamed方式有備份標籤檔案,可以同時執行多個備份。

④ BACKUP FROM:備份源standby還是master。

⑤ START TIME:備份開始的物理時間。

⑥ LABEL:備份標籤。

backup_label檔案最重要的作用是記錄資料庫恢復的起始位置,在資料庫恢復時使用,其次是對本次備份的一個標識及記錄一些備份的參考資訊。

最後呼叫SendXlogRecPtrResult函式把備份開始時的日誌位置傳送給客戶端。

perform_base_backup函式在/* Collect information about all tablespaces */while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL) 迴圈讀取每個表空間的資料檔案,通過sendTablespace呼叫sendDir,把表空間目錄下的資料檔案傳送給客戶端備份工具。在把全部檔案傳送給客戶備份工具後,呼叫do_pg_stop_backup進行停止備份的處理,在do_pg_stop_backup函式中,先解析原來備份的backup_label檔案,獲取備份起始的XLOG位置,寫入XLOG_BACKUP_END到日誌檔案,然後呼叫RequestXLogSwitch進行XLOG檔案段切換,方便歸檔快速完成。請求一次新的檢查點RequestCheckpoint,寫當前備份的歷史檔案“Backup”.檔案,呼叫CleanupBackupHistory清除歷史備份檔案。如果需要等待歸檔則等待日誌歸檔完成,do_pg_stop_backup停止備份結束後,呼叫SendXlogRecPtrResult把備份結束的XLOG位置傳送給客戶端備份工具,伺服器端備份命令的處理流程就結束了。

START_REPLICATION對應的識別符號為T_StartReplicationCmd,處理函式為StartReplication,在StartReplication函式中,首先給客戶端工具傳送CopyBothResponse響應訊息,然後呼叫WalSndSetPercentCountStartLsn設定流複製開始位置,然後設定replication_started為true,啟動正式的流複製過程。

2. tar壓縮包格式備份

tar壓縮包格式備份的處理函式為ReceiveTarFile,具體過程如下。

(1) 根據備份內容(全部還是具體表空間)和是否壓縮,確定檔名稱是base.tar[.gz]還是<tablespaceoid>.tar[.gz]。

(2) 開啟tar檔案,接收資料庫伺服器傳送的COPY資料流,寫入tar檔案,直到複製完整個內容。資料庫伺服器往GsBaseBackup傳送的資料流就是一個壓縮後的tar流。

如前所述,openGauss的tar包格式是自定義的,所以需要實現解包。解包的命令為GsTar,主要有兩個命令列引數。

① -D, --destination=DIRECTORY,解壓後的檔案存放路徑;

② -F, --filename=FILENAME,需要解壓的tar包。

以上內容為備份恢復機制:openGauss全量備份技術的相關內容,後續將接著分享“openGauss增量備份技術”的精彩內容,敬請期待!

 

END