PostgreSQL邏輯備份pg_dump使用及其原理解析

一、原理分析

1、循環調用getopt_long解析命令行參數,將參數保存到static DumpOptions dopt;中 2、判斷參數是否相容,不相容則退出:

  options -s/--schema-only and -a/--data-only cannot be used togetheroptions -c/--clean and -a/--data-only cannot be used togetheroptions --inserts/--column-inserts and -o/--oids cannot be used togetheroption --if-exists requires option -c/--clean

3、調用CreateArchive打開輸出文件,輸出流為fout。該函數使用4個文件封裝了4種不同dump文件格式,增加新文件可以增加新的導出文件類型各自封裝,獨立易于維護。

  CreateArchive->_allocAH:switch (AH->format){case archCustom:InitArchiveFmt_Custom(AH);break;case archNull:InitArchiveFmt_Null(AH);break;case archDirectory:InitArchiveFmt_Directory(AH);break;case archTar:InitArchiveFmt_Tar(AH);break;default:exit_horribly(modulename, "unrecognized file format \"%d\"\n", fmt);}

4、fout是一個重要的全局變量

5、調用ConnectDatabase連接數據庫

6、調用setup_connection,在連接上執行一些SQL語句:

  SELECT pg_catalog.set_config('search_path', '', false);set client_encoding to '%s'//pg_dump -E指定SET ROLE %s//SET DATESTYLE = ISO;SET INTERVALSTYLE = POSTGRES;SET extra_float_digits TO 3;SET synchronize_seqscans TO off;SET statement_timeout = 0;SET lock_timeout = 0;SET idle_in_transaction_session_timeout = 0;SET row_security = off;BEGIN;SET TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ ONLY;

7、為兼容低版本,根據服務器版本號決定一些變量取值

8、調用tblinfo = getSchemaData(fout, &numTables);決定導出哪些數據庫對象。本函數又調用如下函數,值得關注哦。為了存儲每個對象的元數據,這些函數會malloc申請空間,直到pg_dump進程結束才釋放。

  extinfo = getExtensions(fout, &numExtensions);extinfoindex = buildIndexArray(extinfo, numExtensions, sizeof(ExtensionInfo));getExtensionMembership(fout, extinfo, numExtensions);nspinfo = getNamespaces(fout, &numNamespaces);nspinfoindex = buildIndexArray(nspinfo, numNamespaces, sizeof(NamespaceInfo));tblinfo = getTables(fout, &numTables);tblinfoindex = buildIndexArray(tblinfo, numTables, sizeof(TableInfo));getOwnedSeqs(fout, tblinfo, numTables);funinfo = getFuncs(fout, &numFuncs);funinfoindex = buildIndexArray(funinfo, numFuncs, sizeof(FuncInfo));typinfo = getTypes(fout, &numTypes);typinfoindex = buildIndexArray(typinfo, numTypes, sizeof(TypeInfo));getProcLangs(fout, &numProcLangs);getAggregates(fout, &numAggregates);oprinfo = getOperators(fout, &numOperators);oprinfoindex = buildIndexArray(oprinfo, numOperators, sizeof(OprInfo));getAccessMethods(fout, &numAccessMethods);getOpclasses(fout, &numOpclasses);getOpfamilies(fout, &numOpfamilies);getTSParsers(fout, &numTSParsers);getTSTemplates(fout, &numTSTemplates);getTSDictionaries(fout, &numTSDicts);getTSConfigurations(fout, &numTSConfigs);getForeignDataWrappers(fout, &numForeignDataWrappers);getForeignServers(fout, &numForeignServers);getDefaultACLs(fout, &numDefaultACLs);collinfo = getCollations(fout, &numCollations);collinfoindex = buildIndexArray(collinfo, numCollations, sizeof(CollInfo));getConversions(fout, &numConversions);getCasts(fout, &numCasts);getTransforms(fout, &numTransforms);inhinfo = getInherits(fout, &numInherits);getEventTriggers(fout, &numEventTriggers);processExtensionTables(fout, extinfo, numExtensions);flagInhTables(tblinfo, numTables, inhinfo, numInherits);getTableAttrs(fout, tblinfo, numTables);flagInhAttrs(fout->dopt, tblinfo, numTables);getIndexes(fout, tblinfo, numTables);getExtendedStatistics(fout);getConstraints(fout, tblinfo, numTables);getTriggers(fout, tblinfo, numTables);getRules(fout, &numRules);getPolicies(fout, tblinfo, numTables);getPublications(fout);getPublicationTables(fout, tblinfo, numTables);getSubscriptions(fout);

對于每個getXXXs函數都將執行下面流程,以getTables為例:

1)根據服務器版本號查詢系統表,讀出對象的元數據信息

2)malloc內存空間并將查詢結果存放到對象的數據結構中,TableInfo

3)對于每條元數據信息,調用selectDumpableTable標記需要導出的表,如果-t指定導出表,遍歷該列表,得到對應表并標記:DUMP_COMPONENT_ALL;-T指定刪除表,標記tbinfo->dobj.dump = DUMP_COMPONENT_NONE

4)dumpIdMap[dobj->dumpId] = dobj;將導出表的元數據存放到dumpIdMap數組中

5)在導出表上執行LOCK TABLE %s IN ACCESS SHARE MODE

6)將所有元數據信息保存后,執行SET statement_timeout = 0保證語句不超時,能夠一直執行下去

9、調用getTableData函數,獲取表對應的數據。實際上,并不是表真正數據,而是為表數據建立一個“導出對象”,將來導出時,依據導出對象獲取真是的數據再導出。雖然先把導出對象放到AH->toc鏈表上,真正導出時導出數據,不會占用大量內存空間,但是針對這些元數據,當表特別多的時候,由于不到進程退出不釋放內存,占用內存還是非常可觀的。

該函數調用makeTableDataInfo:

1)view、外部表、分區表字表(從父表導出)和unlogged permanent table不用導出

2)判斷該表是否制定導出時被排除

3)malloc一個TableDataInfo,保存表信息

    typedef struct _tableDataInfo{DumpableObject dobj;TableInfo  *tdtable;    /* link to table to dump */bool    oids;      /* include OIDs in data? */char     *filtercond;    /* WHERE condition to limit rows dumped */} TableDataInfo;

4)tdinfo->dobj.catId.tableoid、tdinfo->dobj.catId.oid、tdinfo->dobj.name、tdinfo->dobj.namespace 信息,并將dobj保存到dumpIdMap數組

10、如果需要導出大對象,調用getBlobs,同上也是保存到數組,并沒有真正導出數據

11、調用getDependencies重新整理每個對象的依賴關系。

12、getDumpableObjects從dumpIdMap數組中獲取dump對象

13、sortDumpableObjectsByTypeName、sortDataAndIndexObjectsBySize(如果是并行dump,需要按表大小排序)、sortDumpableObjects把所有對象重新排列:不同類型對象導出優先級依賴于dbObjectTypePriority數組;相同類型按名稱排序

  static const int dbObjectTypePriority[] ={1,  /* DO_NAMESPACE */4,  /* DO_EXTENSION */5,  /* DO_TYPE */5,  /* DO_SHELL_TYPE */6,  /* DO_FUNC */7,  /* DO_AGG */8,  /* DO_OPERATOR */8,  /* DO_ACCESS_METHOD */9,  /* DO_OPCLASS */9,  /* DO_OPFAMILY */3,  /* DO_COLLATION */11,  /* DO_CONVERSION */18,  /* DO_TABLE */20,  /* DO_ATTRDEF */28,  /* DO_INDEX */29,  /* DO_STATSEXT */30,  /* DO_RULE */31,  /* DO_TRIGGER */27,  /* DO_CONSTRAINT */32,  /* DO_FK_CONSTRAINT */2,  /* DO_PROCLANG */10,  /* DO_CAST */23,  /* DO_TABLE_DATA */24,  /* DO_SEQUENCE_SET */19,  /* DO_DUMMY_TYPE */12,  /* DO_TSPARSER */14,  /* DO_TSDICT */13,  /* DO_TSTEMPLATE */15,  /* DO_TSCONFIG */16,  /* DO_FDW */17,  /* DO_FOREIGN_SERVER */32,  /* DO_DEFAULT_ACL */3,  /* DO_TRANSFORM */21,  /* DO_BLOB */25,  /* DO_BLOB_DATA */22,  /* DO_PRE_DATA_BOUNDARY */26,  /* DO_POST_DATA_BOUNDARY */33,  /* DO_EVENT_TRIGGER */38,  /* DO_REFRESH_MATVIEW */34,  /* DO_POLICY */35,  /* DO_PUBLICATION */36,  /* DO_PUBLICATION_REL */37  /* DO_SUBSCRIPTION */};

14、dumpEncoding、dumpStdStrings、dumpSearchPath導出編碼信息,使用雙向鏈表TOCEntry保存導出對象。例如:

  newToc->defn:"SET client_encoding='UTF8';\n"SET standard_conforming_string='on';SELECT pg_catalog.set_config('search_path','',false);\n

15、dumpDatabase導出本鏈接對應的目的數據庫信息,同樣是newToc,newToc->defn:CREATE DATABASE yzs WITH TEMPLATE=template0 ENCODING='UTF8' LC_COLLATE='zh_CN.UTF-8' LC_CTYPE='zh_CN.UTF-8'

16、遍歷所有對象,對于每個對象調用dumpDumpableObject,本函數用一堆諸如dumpNamespace、dumpExtension等,將其插入循環鏈表。

  for (i = 0; i < numObjs; i++)dumpDumpableObject(fout, dobjs[i]);

--------------------------以上所有導出,不真正導出數據----------------------------

17、遍歷鏈表標記哪些對象Toc entry需要導出:ProcessArchiveRestoreOptions

18、如果導出格式時plain,則調用RestoreArchive,輸出到文件顯示的是SQL語句,不再是不可識別的二進制文件

19、關閉句柄釋放資源CloseArchive,根據函數指針調用不同文件類型的_CloseArchive(導出數據到文件?RestoreArchive -> restore_toc_entry ->?_printTocEntry)

二、不同格式的處理函數

-F, --format=c|d|t|p output file format (custom, directory, tar,plain text (default))

目前,pg_dump支持4種導出格式:

custum(pg_backup_custum.c):導出二進制格式的文件。包括文件頭和文件體。文件體是一個鏈表,保存每個備份對象,每個可備份對象都有一套統一的結構表示,支持壓縮

plain(pg_backup_null.c):把SQL腳本內容輸出到標準輸出,默認方式

file(pg_backup_file.c):導出包括備份一個主文件和一些輔助文件,主文件方式類似于custom文件格式,輔助文件是數據文件,每個輔助文件對應備份對象中的一個表,需要和-f一起使用

tar(pg_backup_tar.c):文件備份基本類似“file”方式,但最后備份的所有文件都要歸檔到一個tar文件。文件最大大小為8GB(受限于tar file format)

PostgreSQL通過函數指針來實現這四種導出格式。在pg_backup_archive.h文件中有諸如下面的大量函數指針:

  typedef void (*ClosePtrType) (ArchiveHandle *AH);typedef void (*ReopenPtrType) (ArchiveHandle *AH);typedef void (*ArchiveEntryPtrType) (ArchiveHandle *AH, TocEntry *te);

這些函數指針,在下面文件里分別初始化:

  pg_backup_custum.c->InitArchiveFmt_Custom(ArchiveHandle *AH)pg_backup_null.c->InitArchiveFmt_Null(ArchiveHandle *AH)pg_backup_file.c->InitArchiveFmt_Directory(ArchiveHandle *AH)pg_backup_tar->InitArchiveFmt_Tar(ArchiveHandle *AH)

在數據結構ArchiveHandle中使用了大量函數指針,是的在初始化不同導出文件格式的Archive結構時,能為處理函數賦值為各自不同的處理函數。這樣在pg_dump.c中只需要根據用戶指定的文件格式的參數,就可以調用相應的處理函數。見第一部分的第3步。

概況的說,pg_dump導出的內容可以分為數據庫對象的定義和數據。數據庫對象的定義導出時通過查詢系統表把對應元數據信息讀取出來后,把該對象的各類信息置于一個鏈表上包括其依賴對象的oid。而具體的數據,也就是每個數據包的數據也被抽象為一個數據庫對象,保存在此鏈表中。通過調節導出順序把數據庫對象的定義導出然后導出數據,置于通過鏈表中對應數據對象節點的信息,執行相應的SQL語句,從表中讀出數據然后導出寫出去。所以,在內存中只是鏈表上對象的定義,數據是邊讀邊寫出的,可以使用流式讀出。

三、使用方法

三、使用方法

1)以目錄格式導出,需要和-f一起使用。toc.dat保存所有可導出對象的信息(表定義等),其他文件是數據,以表的oid為命名,test是目錄。

[postgres@localhost ~]$ pg_dump --format=d yzs -f test
[postgres@localhost ~]$ cd test
[postgres@localhost test]$ ll
total 8
-rw-rw-r--. 1 postgres postgres   31 Mar 23 06:07 3010.dat.gz
-rw-rw-r--. 1 postgres postgres 2124 Mar 23 06:07 toc.dat

2)導出SQL語句到test.sql中

[postgres@localhost ~]$ pg_dump --format=p yzs -f test.sql

3)以二進制格式輸出

[postgres@localhost ~]$ pg_dump --format=c -f test yzs

4)以tar格式輸出。與d格式不同在于多了一個restore.sql文件(plain格式文件),并將所有文件打包成一個文件

[postgres@localhost ~]$ pg_dump --format=t -f test yzs
[postgres@localhost ~]$ tar -xvf test
toc.dat
3010.dat
restore.sql

5)僅導出數據庫結構(不指定庫,默認是postgres)

pg_dump -s yzs -f 1.sql

6)導出時導出drop database和create database語句。需注意,導入時如有用戶連接這該庫,則drop語句執行失敗

pg_dump -s yzs -C -c -f 1.txt

7、-t指定導出某些表,只導出item開頭的表等對象

pg_dump -t temp* -f 1.txt yzs

8、-n只導出指定的schema,可以多個-n;-N指定不導出的schema

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/41404.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/41404.shtml
英文地址,請注明出處:http://en.pswp.cn/news/41404.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

uni-app中監聽網絡狀態,并在嵌入webView頁面的組件中添加網絡監測

uni-app中監聽網絡狀態&#xff0c;并在嵌入webView頁面的組件中添加網絡監測 uni-app中監聽網絡狀態 下載插件 打開網絡異常組件頁面&#xff0c;點擊"下載插件并導入HBuilderX"按鈕&#xff0c;打開HBuilderX軟件后&#xff0c;選擇需要導入插件的項目&#xff…

機器學習與模型識別1:SVM(支持向量機)

一、簡介 SVM是一種二類分類模型&#xff0c;在特征空間中尋找間隔最大的分離超平面&#xff0c;使得數據得到高效的二分類。 二、SVM損失函數 SVM 的三種損失函數衡量模型的性能。 1. 0-1 損失&#xff1a; 當正例樣本落在 y0 下方則損失為 0&#xff0c;否則損失為…

系統架構設計師-信息安全技術(1)

目錄 一、信息安全基礎 1、信息安全五要素 2、網絡安全漏洞 3、網絡安全威脅 4、安全措施的目標 二、信息加解密技術 1、對稱加密 2、非對稱加密 3、加密算法對比 三、密鑰管理技術 1、數字證書 2、PKI公鑰體系 四、訪問控制技術 1、訪問控制基本模型 2、訪問控制的實現技術…

【Linux命令詳解 | ssh命令】 ssh命令用于遠程登錄到其他計算機,實現安全的遠程管理

文章標題 簡介一&#xff0c;參數列表二&#xff0c;使用介紹1. 連接遠程服務器2. 使用SSH密鑰登錄2.1 生成密鑰對2.2 將公鑰復制到遠程服務器 3. 端口轉發3.1 本地端口轉發3.2 遠程端口轉發 4. X11轉發5. 文件傳輸與遠程命令執行5.1 文件傳輸5.1.1 從本地向遠程傳輸文件5.1.2 …

TensorFlow 的基本概念和使用場景

簡介 TensorFlow 是一個開源的人工智能框架&#xff0c;由 Google 公司開發&#xff0c;用于構建和訓練機器學習模型。 TensorFlow 的基本概念包括&#xff1a; 1. 張量 (Tensor): TensorFlow 中的基本數據結構&#xff0c;可以理解為多維數組。 2. 計算圖 (Graph): TensorF…

深度學習入門-3-計算機視覺-圖像分類

1.概述 圖像分類是根據圖像的語義信息對不同類別圖像進行區分&#xff0c;是計算機視覺的核心&#xff0c;是物體檢測、圖像分割、物體跟蹤、行為分析、人臉識別等其他高層次視覺任務的基礎。圖像分類在許多領域都有著廣泛的應用&#xff0c;如&#xff1a;安防領域的人臉識別…

軟考筆記——9.軟件工程

軟件工程的基本原理&#xff1a;用分階段的生命周期計劃嚴格管理、堅持進行階段評審、實現嚴格的產品控制、采用現代程序設計技術、結果應能清除的審查、開發小組的人員應少而精、承認不斷改進軟件工程事件的必要性。 軟件工程的基本要素&#xff1a;方法、工具、過程 軟件生…

babylonjs基于自定義網格生成圍欄動畫

效果&#xff1a; import { Vector3, Mesh, MeshBuilder, StandardMaterial, Texture, Animation, Color3 } from "babylonjs/core"; import imgUrl from "./image/headerwangge2.png" // 創建模型護欄特效 export default class CreateRail {constructor…

cocos creator 設置精靈鏡像翻轉效果

在 Cocos Creator 中&#xff0c;你可以通過代碼來設置精靈節點的鏡像翻轉效果。具體來說&#xff0c;你可以使用精靈節點的 setScale 方法來實現這一點。以下是在代碼中設置水平鏡像翻轉和垂直鏡像翻轉的示例&#xff1a; // 獲取精靈節點的引用 let spriteNode cc.find(&qu…

小程序swiper一個輪播顯示一個半內容且實現無縫滾動

效果圖&#xff1a; wxml&#xff08;無縫滾動&#xff1a;circular"true"&#xff09;&#xff1a; <!--components/tool_version/tool_version.wxml--> <view class"tool-version"><swiper class"tool-version-swiper" circul…

數模論文寫作細節要求

目錄 優秀論文必要條件 數學建模的基本思路 第一步&#xff1a;了解問題——查文獻、找數據 第二步&#xff1a;闡述要解決什么問題、用什么方法 其余步驟&#xff1a;給出數學模型、計算求解、對比結果與真實情況、應用于現實問題。 使用某種數學方法的理由和依據 創…

Python爬蟲性能優化:多進程協程提速實踐指南

各位大佬們我又回來了&#xff0c;今天我們來聊聊如何通過多進程和協程來優化Python爬蟲的性能&#xff0c;讓我們的爬蟲程序6到飛起&#xff01;我將會提供一些實用的解決方案&#xff0c;讓你的爬蟲速度提升到新的高度&#xff01; 1、多進程提速 首先&#xff0c;讓我們來看…

cs231n assignment2 q5 PyTorch on CIFAR-10

文章目錄 嫌啰嗦直接看源碼Q5 :PyTorch on CIFAR-10three_layer_convnet題面解析代碼輸出 Training a ConvNet題面解析代碼輸出 ThreeLayerConvNet題面解析代碼輸出 Train a Three-Layer ConvNet題面解析代碼輸出 Sequential API: Three-Layer ConvNet題面解析代碼輸出 CIFAR-1…

SpringBoot整合ArtemisMQ筆記

SpringBoot整合ArtemisMQ筆記 本案例是springboot2.4.2整合Apache ArtemisMQ, 發送jms信息和訂閱jms消息的代碼示例pom配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-artemis</artifactId><…

BT利器之wazuh

目錄 一、什么是wazuh 二、wazuh的安裝 1.倉庫安裝 2.虛擬機OVA安裝 3.其他安裝方式 三、淺析wazuh的規則、解碼器等告警原理以及主動響應 1.主動響應(active-response) 2.告警信息(alerts) 3.規則以及解碼器(rules and decoders) 3.1.規則 3.2.解碼器 4.linux后門r…

力扣75——圖深度優先搜索

總結leetcode75中的圖深度優先搜索算法題解題思路。 上一篇&#xff1a;力扣75——二叉搜索樹 力扣75——圖深度優先搜索 1 鑰匙和房間2 省份數量3 重新規劃路線4 除法求值1-4 解題總結 1 鑰匙和房間 題目&#xff1a; 有 n 個房間&#xff0c;房間按從 0 到 n - 1 編號。最初…

【Matter】基于Ubuntu 22.04搭建matter開發環境:chip-tool 配網之 matter-over-wifi

前言 主要是記錄一下學習過程&#xff0c;梳理下思路&#xff0c;拋轉~ 官方的開發環境&#xff0c;基于Linux版本&#xff0c;官方的環境是基于樹莓派環境的&#xff0c;原理其實也比較明了&#xff0c;目的也比較明確&#xff0c;就是達到Linux 主機和wifi 路由在同一局域網…

SpringBoot攜帶Jre綠色部署項目

文章目錄 SpringBoot攜帶Jre綠色部署運行項目1. 實現步驟2. 自測項目文件目錄及bat文件內容&#xff0c;截圖如下&#xff1a;2-1 項目文件夾列表&#xff1a;2-2. bat內容 3. 擴展&#xff1a; 1.6-1.8版本的jdk下載 SpringBoot攜帶Jre綠色部署運行項目 說明&#xff1a; 實…

256創作紀念日

不知不覺已經是寫博客的第256天了&#xff0c;從一個躺平的人變成一個為一件事能堅持并不斷去做是真的很爽&#xff0c;回過頭看看自己&#xff0c;寫了好多東西&#xff0c;也慢慢在成長&#xff0c;不再是以前那個只會玩的小孩了。 1、自我介紹 我是來自西安的一名準大三學…

Data Abstract for .NET and Delphi Crack

Data Abstract for .NET and Delphi Crack .NET和Delphi的數據摘要是一套或RAD工具&#xff0c;用于在.NET、Delphi和Mono中編寫多層解決方案。NET和Delphi的數據摘要是一個套件&#xff0c;包括RemObjects.NET和Delphi版本的數據摘要。RemObjects Data Abstract允許您創建訪問…