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.mzph.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允许您创建访问…