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