PG_dump 源码笔记

PostgreSQL逻辑备份-pg_dump 可以看到,Parallel Loader 脚本的执行速度比 pg_dump 和 pg_restore 快了 3 倍以上。在这种情况下,-j 选项没有用,因为 pg_dump/pg_restore 每个表只运行一个线程,它。pg_dump/pg_restore 是可以将数据从一个数据库迁移到另一个数据库。可以使用 -j 选项来指定执行 pg_dump 和 pg_restore 时要使用的线程数。脚本将单个大表进行迁移,而 pg_dump/pg_restore 可用于迁移其余的表。 阅读详情

PG_DUMP 源码简析

  pg_dump是一个用于备份PostgreSQL 数据库的工具。它甚至可以在数据库正在使用的时候进行完整一致的备份。pg_dump并不阻塞其它用户对数据库的访问(读或者写)。

转储格式可以是一个脚本或者归档文件。脚本转储的格式是纯文本,它包含许多 SQL 命令,这些 SQL 命令可以用于重建该数据库并将之恢复到保存成脚本的时候的状态。使用psql从这样的脚本中恢复。甚至可以用于在其它机器甚至是其它硬件体系的机器上重建该数据库,通过对脚本进行一些修改,甚至可以在其它 SQL 数据库产品上重建该数据库。

归档文件格式必须和pg_restore一起使用重建数据库。它们允许pg_restore对恢复什么东西进行选择,或者甚至是在恢复之前对需要恢复的条目进行重新排序。归档文件也是设计成可以跨平台移植的。

如果一种候选文件格式和pg_restore结合,那么pg_dump就能提供一种灵活的归档和传输机制。 pg_dump可以用于备份整个数据库,然后就可以使用 pg_restore检查这个归档和/或选择要恢复的数据库部分。最灵活的输出文件格式是"custom"(自定义)格式(-Fc)和 "directory"(目录)格式(-Fd)。它们允许对归档元素进行选取和重新排列,支持并行恢复并且缺省时是压缩的。 "directory"格式是唯一支持并行转储的格式。

1、     PG_DUMP 使用

pg_dump [connection-option...][option...] [dbname]

选项说明

dbname

将要转储的数据库名。如果没有声明这个参数,那么使用环境变量PGDATABASE。如果那个环境变量也没声明,那么使用发起连接的用户名。

-a/--data-only

只输出数据,不输出模式(数据定义)。转储表数据、大对象和序列值。

-b/--blobs

在转储中包含大对象。除非指定了--schema, --table, --schema-only开关,否则这是默认行为。因此-b 开关仅用于在选择性转储的时候添加大对象。

-c/--clean

输出命令在输出创建数据库命令之前先清理(drop)该数据库对象。(如果任何对象在目标数据库中不存在,则转储可能生成一些无害的错误消息。)

-C/--create

以一条创建该数据库本身并且与这个数据库连接命令开头进行输出。如果是这种形式的脚本,那么你在运行脚本之前和目的安装中的哪个数据库连接就不重要了。如果也声明了 --clean,那么脚本在重新连接到数据库之前删除并重新创建目标数据库。

-E encoding /--encoding=encoding

以指定的字符集编码创建转储。缺省时,转储是按照数据库编码创建的。另外一个获取同样结果的方法是将PGCLIENTENCODING环境变量设置为期望的转储编码。

-f file /--file=file

输出文件名。文件基础输出格式时可以省略这个参数,这种情况下使用标准输出。但是,在声明目标目录而不是文件时必须给出目录输出格式。在这种情况下,目录通过pg_dump创建并且必须之前不存在。

-F format/--format=format

选择输出的格式。format可以是下列之一:

p
plain

纯文本SQL脚本文件(缺省)。

c
custom

适合输入到pg_restore里的自定义格式归档。加上目录输出格式,这是最灵活的格式,它允许在转储期间对已归档的条目进行手动选择和重新排列。这个格式缺省的时候是压缩的。

d
directory

适合输入到pg_restore里的目录格式归档。这将创建一个目录,该目录包含一个为每个被转储的表和二进制大对象的文件,加上一个号称目录的文件,该文件以pg_restore可读的机器可读格式描述转储的对象。目录格式归档可以用标准Unix工具操作;例如,在非压缩归档中的文件可以用 gzip工具压缩。这个格式缺省的时候是压缩的,并且也支持并行转储。

t
tar

适合输入到pg_restore里的tar归档文件。 tar格式兼容目录格式;提取tar格式归档产生一个有效的目录格式归档。不过, tar格式不支持压缩并且限制单独的表为8 GB。还有,表数据条目的相关顺序在转储期间不能更改。

-j njobs /--jobs=njobs

通过同时转储njobs表并行运行转储。该选项减少了转储的时间,但是也增加了数据库服务器的负载。可以只将这个选项用于目录输出格式,因为这是多进程可以同时写它们的数据的唯一的输出格式。

pg_dump将打开njobs + 1个到数据库的连接,所以使用时需要根据max_connections值进行设置,不能大于该值。

-n schema / --schema=schema

只转储匹配schema的模式内容,包括模式本身以及其中包含的对象。如果没有声明这个选项,所有目标数据库中的非系统模式都会被转储出来。可以使用多个-n选项指定多个模式。同样,schema参数将按照psql 的\d命令的规则被解释为匹配模式,因此可以使用通配符匹配多个模式。在使用通配符的时候,最好用引号进行界定,以防止 shell 将通配符进行扩展。

-N schema /--exclude-schema=schema

不转储任何匹配schema的模式内容。模式匹配规则与-n完全相同。可以指定多个-N以排除多种匹配的模式。

如果同时指定了-n和-N,那么将只转储匹配-n 但不匹配-N的模式。如果出现-N但是不出现-n,那么匹配-N的模式将不会被转储。

-o /--oids

作为数据的一部分,为每个表都输出对象标识(OIDs)。如果你的应用需要OID字段的话(比如在外键约束中用到),那么使用这个选项。否则,不应该使用这个选项。

-O /--no-owner

不把对象的所有权设置为对应源数据库。pg_dump默认发出 ALTER OWNER或SET SESSION AUTHORIZATION 语句以设置创建的数据库对象的所有权。如果这些脚本将来没有被超级用户 (或者拥有脚本中全部对象的用户)运行的话将会失败。-O 选项就是为了让该脚本可以被任何用户恢复并且将脚本中对象的所有权赋予该选项指定的用户。

-s/--schema-only

只输出对象定义(模式),不输出数据。

-S username/--superuser=username

指定关闭触发器时需要用到的超级用户名。它只有使用了--disable-triggers 的时候才有影响。一般情况下最好不要输入这个参数,而是用超级用户启动生成的脚本。

-t table/--table=table

只转储出匹配table的表(或视图、序列、外表)。可以使用多个-t选项匹配多个表。同样,table 参数将按照psql的\d命令的规则被解释为匹配模式,因此可以使用通配符匹配多个模式。在使用通配符的时候,最好用引号进行界定,以防止 shell 将通配符进行扩展。

使用了-t之后,-n和-N选项就失效了。因为被-t 选中的表将无视-n和-N选项而被转储,同时除了表之外的其他对象不会被转储。

-T table/--exclude-table=table

不要转储任何匹配table模式的表。模式匹配规则与-t完全相同。可以指定多个-T以排除多种匹配的表。

如果同时指定了-t和-T,那么将只转储匹配-t 但不匹配-T的表。如果出现-T但是不出现-t,那么匹配 -T的表将不会被转储。

-v/--verbose

指定冗余模式。这样将令pg_dump 输出详细的对象评注以及转储文件的启停时间和进度信息到标准错误上。

-V/--version

  显示pg_dump版本

-x/--no-privileges --no-acl

禁止转储访问权限(grant/revoke 命令)。

-Z 0..9
--compress=0..9

指定要使用的压缩级别。0表示不压缩。对于自定义归档格式,指定单个表数据段的压缩,并且缺省是中等水平的压缩。对于纯文本输出,设置非零压缩级别会压缩整个输出文件,就像通过gzip反馈回来一样;但是缺省是不压缩的。 tar归档模式当前不支持压缩。

--binary-upgrade

此选项用于在线升级工具。不建议也不支持用于其他目的。该选项的行为可能会在将来的版本中改变。

--column-inserts
--attribute-inserts

把数据转储为带有明确字段名的INSERT命令 (INSERTINTO table (column, ...) VALUES ...)。这样会导致恢复非常缓慢,它主要用于制作那种可以用于其它非 PostgreSQL数据库的转储。由于这个选项为每条记录都生成一条命令,因此如果其中某一行命令出错,那么将仅有该行数据丢失,而不是整个表的数据丢失。

--disable-dollar-quoting

这个选项关闭使用美元符界定函数体。强制它们用 SQL 标准的字符串语法的引号包围。

--disable-triggers

这个选项只是和创建仅有数据的转储相关。它告诉pg_dump 包含在恢复数据时临时关闭目标表上触发器的命令。如果在表上有参照完整性检查或者其它触发器,而恢复数据的时候不想重载他们,那么就应该使用这个选项。

--exclude-table-data=table

不要转储任何匹配table模式的表。模式匹配规则与-t完全相同。可以给出多个--exclude-table-data 以排除多个匹配的表。当你需要指定表的定义时该选项是有用的,即使你不需要表里面的数据。

--inserts

将数据输出为的INSERT命令(而不是COPY)。这样会导致恢复非常缓慢。这个选项主要用于制作那种可以用于其它非PostgreSQL数据库的转储。

--lock-wait-timeout=timeout

在转储开始的时候不要等待请求一个共享表锁。相反,如果无法在指定的 timeout内锁住表则失败。 timeout可以用任意SET statement_timeout接受的格式声明

--no-security-labels

不转储安全标签。

--no-synchronized-snapshots

该选项允许在9.2以前的服务器上运行pg_dump -j,参阅-j 参数的文档获取更多信息。

--no-tablespaces

忽略表空间

--no-unlogged-table-data

不要转储未记录表的内容。该选项对于表定义(模式)是否转储没有影响;它只阻止转储表的数据。当从备用服务器转储时,未记录表中的数据总是排除。

--quote-all-identifiers

强制给所有标识符加上引号。这在转储一个数据库到一个可能引入了额外关键字的新版本中时可能是有用的。

--section=sectionname

只转储命名的章节。该章节名可以是pre-data, data, 或post-data。可以多次声明这个选项以选择多个章节。缺省是转储所有章节。

数据章节包含实际的表数据、大对象内容和序列值。原始数据项包含索引、触发器、规则和约束(除了验证检查约束)的定义。之前的数据项包含所有其他数据定义项。

--serializable-deferrable

为转储使用一个可串行化的事务,以保证使用的快照和稍后的数据库状态一致;做这些是通过等待事务流中的一个点,该点没有异常会出现,所以不会有转储失败或导致其他事务 serialization_failure而回滚的风险。获取关于事务隔离和并发控制的更多信息。

--use-set-session-authorization

输出符合 SQL 标准的SET SESSIONAUTHORIZATION命令而不是ALTER OWNER 命令来确定对象所有权。这样令转储更加符合标准,但是如果转储文件中的对象的历史有些问题,那么可能不能正确恢复。并且,使用SET SESSION AUTHORIZATION 的转储需要数据库超级用户的权限才能转储成功,而ALTER OWNER需要的权限则低得多。

-?
--help

显示关于pg_dump命令行参数的帮助。

控制数据库的连接参数:

-d dbname
--dbname=dbname

声明要连接的数据库名称。相当于在命令行中声明dbname 作为第一个非选项参数。

-h host
--host=host

指定运行服务器的主机名。如果数值以斜杠开头,则被用作到 Unix 域套接字的路径。缺省从PGHOST环境变量中获取(如果设置了的话),否则,尝试一个 Unix 域套接字连接。

-p port
--port=port

指定服务器正在侦听的 TCP 端口或本地 Unix 域套接字文件的扩展(描述符)。缺省使用PGPORT环境变量(如果设置了的话),否则,编译时的缺省值。

-U username
--username=username

连接的用户名。

-w
--no-password

从不发出密码提示问题。如果服务器要求密码认证并且密码不可用于其他意思如 .pgpass文件,则连接尝试将会失败。该选项在批量工作和不存在用户输入密码的脚本中很有帮助。

-W
--password

数据库连接时需要密码

--role=rolename

指定创建转储的角色名。这个选项导致连接到数据库之后 pg_dump 发出一个SET ROLE rolename命令。当认证的用户(通过-U指定)缺乏 pg_dump所需的权限时是很有用的,可以转变成有所需权限的角色。一些安装有反对作为超级用户直接登录的政策,使用这个选项允许转储不违反该政策。

环境变量

在参数为设置时,获取环境变量值

PGDATABASE
PGHOST
PGOPTIONS
PGPORT
PGUSER

 

用例

将mydb数据库转储到一个 SQL 脚本文件:

$ pg_dump mydb > db.sql

将上述脚本导入一个(新建的)数据库newdb:

$ psql -d newdb -f db.sql

将数据库转储为自定义格式的归档文件

$ pg_dump -Fc mydb > db.dump

将数据库转储为目录格式归档:

$ pg_dump -Fd mydb -f dumpdir

将数据库转储为目录格式归档,并行5个worker工作:

$ pg_dump -Fd mydb -j 5 -f dumpdir

将归档文件导入一个(新建的)数据库newdb:

$ pg_restore -d newdb db.dump

转储一个名为mytab的表:

$ pg_dump -t mytab mydb > db.sql

转储detroit模式中所有以emp开头的表,但是不包括employee_log表:

$ pg_dump -t 'detroit.emp*' -T detroit.employee_log mydb > db.sql

转储所有以east或west开头并以gsm结尾的模式,但是不包括名字中含有test模式:

$ pg_dump -n 'east*gsm' -n 'west*gsm' -N '*test*' mydb > db.sql

同上,不过这一次使用正则表达式的方法:

$ pg_dump -n '(east|west)*gsm' -N '*test*' mydb > db.sql

转储所有数据库对象,但是不包括名字以ts_开头的表:

$ pg_dump -T 'ts_*' mydb > db.sql

在-t等选项中指定大写字母或大小写混合的名字必须用双引号界定,否则将被自动转换为小写。但是因为双引号在 shell 中有特殊含义,所以必须将双引号再放进单引号中。这样一来,要转储一个大小写混合的表名,你就需要像下面这样:

$ pg_dump -t "\"MixedCaseName\"" mydb > mytab.sql

 

2、 PG_DUMP流程图

   



3、 PG_DUMP 逻辑说明

3.1 、参数解析 & 参数冲突校验

1  –a(只备份数据) 与 –s (只备份模式) 冲突

2  -a(只备份数据) 与 –c (删除对象) 冲突

3  –inserts(insert 模式)与 –o(备份oid)冲突

4  --if-exists  与 –c 需同时存在

5  -j大于1时–F 为不能为d

 

3.2 、初始化备份文件格式和文件读取模式

文件格式定义:

typedefenum _archiveFormat

{

       archUnknown = 0,

       archCustom = 1,

       archTar = 3,

       archNull = 4,

       archDirectory = 5

}ArchiveFormat;

 

通过枚举定义文件格式类型,分别对应4中不同的文件格式,分别对应4种不同的处理类型,处理过程参考pg_backup_custom.c,pg_backup_directory.c,pg_backup_null.c,pg_backup_tar.c。

 

文件读取模式定义:

typedefenum _archiveMode

{

       archModeAppend,

       archModeWrite,

       archModeRead

}ArchiveMode;

 

通过枚举定义文件读写方式 分别为追加,写,读 三中模式。

 

 根据参数-F、--format 初始化输出文件格式和模式

1  –F ,--format = a/append

文件格式:archNull 读取模式:archModeAppend

 

2  –F ,--format = c/custom

文件格式:archCustom 读取模式:archModeWrite

 

3  –F ,--format = d/directory

文件格式:archDirectory 读取模式:archModeWrite

 

4  –F ,--format = p/plain

文件格式:archNull 读取模式:archModeWrite

 

5  –F ,--format = t/tar

文件格式:archTar 读取模式:archModeWrite

 

3.3 、创建全局变量结构Archive

Archive结构

typedefstruct Archive

{

       DumpOptions *dopt;                   /* 备份参数 */

       RestoreOptions *ropt;           /* 恢复参数*/

 

       int                 verbose;

       char    *remoteVersionStr;         /* 备份的数据库版本 str类型*/

       int                 remoteVersion;      /* 备份的数据库版本 int类型 */

       bool        isStandby;             /*是否在进行热备份 */

 

       int                 minRemoteVersion;              /* 兼容最低的数据库版本 */

       int                 maxRemoteVersion;

 

       int                 numWorkers;         /* 并发个数 */

       char    *sync_snapshot_id;          /*异步快照id

                                                                       * operation */

 

       /* info needed for string escaping */

       int                 encoding;       /* libpq code for client_encoding */

       bool        std_strings;     /* standard_conforming_strings */

       char   *use_role;        /* Issue SET ROLE to this */

 

       /* error handling */

       bool        exit_on_error; /* whether to exit on SQL errors... */

       int                 n_errors;        /* number of errors (if no die) */

 

       /* The rest is private */

}Archive;

 

ArchiveHandle结构:

struct_archiveHandle

{

       Archive          public;                  /* Public part of archive */

       int                 version;          /* Version of file */

 

       char    *archiveRemoteVersion;  /* When reading an archive, the

                                                                       * version of the dumped DB */

       char    *archiveDumpVersion;           /* When reading an archive, the

                                                                       * version of the dumper */

 

       int                 debugLevel;           /* Used for logging (currently onlyby

                                                         * --verbose) */

       size_t             intSize;          /* Size of an integer in the archive*/

       size_t             offSize;          /* Size of a file offset in thearchive -

                                                         * Added V1.7 */

       ArchiveFormat format;         /* Archive format */

 

       sqlparseInfo sqlparse;            /* state for parsing INSERT data */

 

       time_t            createDate;            /* Date archive created */

 

       /*

        *Fields used when discovering header. A format can always get the

        *previous read bytes from here...

        */

       int                 readHeader;           /* Used if file header has been readalready */

       char    *lookahead;             /*Buffer used when reading header to discover

                                                         * format */

       size_t             lookaheadSize;       /* Size of allocated buffer */

       size_t             lookaheadLen; /* Length of data in lookahead */

       pgoff_t           lookaheadPos; /* Current read position in lookahead buffer */

 

       ArchiveEntryPtr ArchiveEntryPtr;       /* Called for each metadata object */

       StartDataPtr StartDataPtr;     /* Called when table data is about to be

                                                         * dumped */

       WriteDataPtr WriteDataPtr;   /* Called to send some table data to the

                                                         * archive */

       EndDataPtr EndDataPtr;              /* Called when table data dump isfinished */

       WriteBytePtr WriteBytePtr;   /* Write a byte to output */

       ReadBytePtr ReadBytePtr;     /* Read a byte from an archive */

       WriteBufPtr WriteBufPtr;     /* Write a buffer of output to the archive*/

       ReadBufPtr ReadBufPtr;              /* Read a buffer of input from thearchive */

       ClosePtr ClosePtr;                /* Close the archive */

       ReopenPtr ReopenPtr;           /* Reopen the archive */

       WriteExtraTocPtr WriteExtraTocPtr;    /* Write extra TOC entry data

                                                                       * associated with the current archive

                                                                       * format */

       ReadExtraTocPtr ReadExtraTocPtr;      /* Read extr info associated with

                                                                       * archie format */

       PrintExtraTocPtr PrintExtraTocPtr;      /* Extra TOC info for format */

       PrintTocDataPtr PrintTocDataPtr;

 

       StartBlobsPtr StartBlobsPtr;

       EndBlobsPtr EndBlobsPtr;

       StartBlobPtr StartBlobPtr;

       EndBlobPtr EndBlobPtr;

 

       SetupWorkerPtr SetupWorkerPtr;

       WorkerJobDumpPtr WorkerJobDumpPtr;

       WorkerJobRestorePtr WorkerJobRestorePtr;

 

       ClonePtr ClonePtr;               /* Clone format-specific fields */

       DeClonePtr DeClonePtr;              /* Clean up cloned fields */

 

       CustomOutPtr CustomOutPtr;       /* Alternative script output routine */

 

       /* Stuff for direct DB connection */

       char    *archdbname;          /*DB name *read* from archive */

       trivalue   promptPassword;

       char    *savedPassword;      /* password for ropt->username, if known */

       char    *use_role;

       PGconn      *connection;

       /* If connCancel isn't NULL, SIGINThandler will send a cancel */

       PGcancel  *volatile connCancel;

 

       int                 connectToDB; /* Flag to indicate if direct DB connection is

                                                         * required */

       ArchiverOutput outputKind;  /* Flag for what we're currently writing */

       bool        pgCopyIn;             /* Currently in libpq 'COPY IN'mode. */

 

       int                 loFd;                     /* BLOB fd */

       int                 writingBlob;   /* Flag */

       int                 blobCount;            /* # of blobs restored */

 

       char    *fSpec;                   /*Archive File Spec */

       FILE          *FH;                       /*General purpose file handle */

       void    *OF;

       int                 gzOut;                   /* Output file */

 

       struct _tocEntry *toc;           /* Header of circular list of TOCentries */

       int                 tocCount;       /* Number of TOC entries */

       DumpId         maxDumpId;         /* largest DumpId among all TOC entries*/

 

       /* arrays created after the TOC list iscomplete: */

       struct _tocEntry **tocsByDumpId;       /* TOCs indexed by dumpId */

       DumpId     *tableDataId;    /* TABLE DATA ids, indexed by table dumpId */

 

       struct _tocEntry *currToc;     /* Used when dumping data */

       int                 compression;   /* Compression requested on open Possible

                                                         * values for compression: -1

                                                         * Z_DEFAULT_COMPRESSION 0   COMPRESSION_NONE

                                                         * 1-9 levels for gzip compression */

       ArchiveMode mode;                    /* File mode - r or w */

       void    *formatData;           /*Header data specific to file format */

 

       /* these vars track state to avoidsending redundant SET commands */

       char    *currUser;        /*current username, or NULL if unknown */

       char    *currSchema;          /*current schema, or NULL */

       char    *currTablespace; /* current tablespace, orNULL */

       bool        currWithOids; /* current default_with_oids setting */

 

       void    *lo_buf;

       size_t             lo_buf_used;

       size_t             lo_buf_size;

 

       int                 noTocComments;

       ArchiverStage stage;

       ArchiverStage lastErrorStage;

       struct _tocEntry *currentTE;

       struct _tocEntry *lastErrorTE;

};

 

ArchiveHandle结构第一个元素为Archive,可以看做是Archive结构的继承,在保存有Archive成员结构指针的情况下,可以通过指针互转来实现结构的转换,此使用方式类似与c++的多态。

 

初始化 Archive结构变量

Archive*

CreateArchive(constchar *FileSpec, const ArchiveFormat fmt,

        const int compression, ArchiveMode mode,SetupWorkerPtr setupDumpWorker)

函数CreateArchive 通过创建并初始化ArchiveHandle 变量,返回一个Archive 变量。

 

FileSpec需要输出的文件名。

Fmt  文件格式

Compression压缩级别

Mode 文件读取方式

setupDumpWorker多任务启动函数指针。

 

设置参数指针到archive.dopt

 

3.4 、初始化数据库连接

 

3.5 、获取schema oid(ex,in)

如果参数中-n, --schema,-N, --exclude-schema ,不空,则通过nspname查询pg_namespace 获取其oid,在后面获取模式对象时进行过滤。

3.6 、获取表 oid(ex,in)

 如果参数中 -t,--table ,-T, --exclude-table 不空,则通过relname 查询pg_class表,获取其oid

 

SELECT c.oid FROM pg_catalog.pg_class c

       LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace

                                                WHERE c.relkind in ('r', 'S', 'v', 'm', 'f','P')

3.7 、获取需要备份表数据的表oid

 如果参数中 --exclude-table-data不空 ,则通过relname 查询需要忽略器数据的表对象oid。

3.8 、获取系统所有对象

函数原型: TableInfo *getSchemaData(Archive *fout, int *numTablesPtr)

 

返回TableInfo数组对象 以及 numTablesPtr表对象个数。

 

每一种数据对象都定义一种对应的数据结构类型,且都继承于DumpableObject结构,获取到的对象结构通过AssignDumpId函数将结构地址寄存于dumpIdMap数组中,通过objtype指定对象类型,以及通过dump成员变量设置是否需要进行备份。

Objtype类型:

typedefenum

{

       /* When modifying this enum, updatepriority tables in pg_dump_sort.c! */

       DO_NAMESPACE,

       DO_EXTENSION,

       DO_TYPE,

       DO_SHELL_TYPE,

       DO_FUNC,

       DO_AGG,

       DO_OPERATOR,

       DO_ACCESS_METHOD,

       DO_OPCLASS,

       DO_OPFAMILY,

       DO_COLLATION,

       DO_CONVERSION,

       DO_TABLE,

       DO_ATTRDEF,

       DO_INDEX,

       DO_RULE,

       DO_TRIGGER,

       DO_CONSTRAINT,

       DO_FK_CONSTRAINT,                    /* see note for ConstraintInfo */

       DO_PROCLANG,

       DO_CAST,

       DO_TABLE_DATA,

       DO_SEQUENCE_SET,

       DO_DUMMY_TYPE,

       DO_TSPARSER,

       DO_TSDICT,

       DO_TSTEMPLATE,

       DO_TSCONFIG,

       DO_FDW,

       DO_FOREIGN_SERVER,

       DO_DEFAULT_ACL,

       DO_TRANSFORM,

       DO_BLOB,

       DO_BLOB_DATA,

       DO_PRE_DATA_BOUNDARY,

       DO_POST_DATA_BOUNDARY,

       DO_EVENT_TRIGGER,

       DO_REFRESH_MATVIEW,

       DO_POLICY

}DumpableObjectType;

 

Dump备份级别:

#defineDUMP_COMPONENT_NONE                     (0)

#defineDUMP_COMPONENT_DEFINITION    (1 <<0)

#defineDUMP_COMPONENT_DATA                     (1<< 1)

#defineDUMP_COMPONENT_COMMENT             (1<< 2)

#defineDUMP_COMPONENT_SECLABEL             (1<< 3)

#defineDUMP_COMPONENT_ACL                 (1<< 4)

#defineDUMP_COMPONENT_POLICY           (1<< 5)

#defineDUMP_COMPONENT_USERMAP              (1<< 6)

#defineDUMP_COMPONENT_ALL                 (0xFFFF)

 

1 获取扩展对象:pg_extensions

ExtensionInfo*getExtensions(Archive *fout, int *numExtensions)

2 获取扩展成员pg_depend

  Void getExtensionMembership(Archive *fout,ExtensionInfo extinfo[],

                                      int numExtensions)

3 获取名空间pg_namespace

  NamespaceInfo *getNamespaces(Archive *fout,int *numNamespaces)

 

4 获取表对象pg_class  relkind in ('S','r','v','c','m','f','P')

TableInfo*getTables(Archive *fout, int *numTables)

 

5 获取队列

   Void getOwnedSeqs(Archive *fout, TableInfotblinfo[], int numTables)

 

6 获取函数对象

   FuncInfo *getFuncs(Archive *fout, int *numFuncs)

 

7 获取数据类型

  TypeInfo *getTypes(Archive *fout, int*numTypes)

 

8 获取语言类型

 ProcLangInfo *getProcLangs(Archive *fout, int*numProcLangs)

 

9 获取聚合函数

AggInfo*getAggregates(Archive *fout, int *numAggs)

 

10 获取操作符重载对象

OprInfo*getOperators(Archive *fout, int *numOprs)

 

11 获取索引对象

AccessMethodInfo*getAccessMethods(Archive *fout, int *numAccessMethods)

 

12 获取索引操作符类

OpclassInfo*getOpclasses(Archive *fout, int *numOpclasses)

 

13 操作符族

OpfamilyInfo*getOpfamilies(Archive *fout, int *numOpfamilies)

14 文本解析器

TSParserInfo*getTSParsers(Archive *fout, int *numTSParsers)

15 文本搜索模板

TSTemplateInfo*getTSTemplates(Archive *fout, int *numTSTemplates)

16 文本搜索字典

TSDictInfo*getTSDictionaries(Archive *fout, int *numTSDicts)

17 文本搜索配置

TSConfigInfo*getTSConfigurations(Archive *fout, int *numTSConfigs)

18 存储外部数据封装器

FdwInfo*getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)

19 储外部服务器

ForeignServerInfo*getForeignServers(Archive *fout, int *numForeignServers)

20 新创建对象的初始化权限

DefaultACLInfo*getDefaultACLs(Archive *fout, int *numDefaultACLs)

 

21 排序规则

CollInfo*getCollations(Archive *fout, int *numCollations)

22 编码转换信息

ConvInfo*getConversions(Archive *fout, int *numConversions)

23 存储数据类型转换路径

CastInfo*getCasts(Archive *fout, int *numCasts)

24 pg_transform

TransformInfo*getTransforms(Archive *fout, int *numTransforms)

25 继承对象

InhInfo*getInherits(Archive *fout, int *numInherits)

 

26 分区表

PartInfo*getPartitions(Archive *fout, int *numPartitions)

27 时间触发器

EventTriggerInfo*getEventTriggers(Archive *fout, int *numEventTriggers)

28 处理扩展表

Void processExtensionTables(Archive*fout, ExtensionInfo extinfo[],

                                      int numExtensions)

29 在tbinfo中扩展继承信息

staticvoid

flagInhTables(TableInfo*tblinfo, int numTables,

                       InhInfo *inhinfo, int numInherits)

30 为分区表指定分区范围,以及父表信息

staticvoid

flagPartitions(TableInfo*tblinfo, int numTables,

                       PartInfo *partinfo, int numPartitions)

31 获取表对象附加属性

void

getTableAttrs(Archive*fout, TableInfo *tblinfo, int numTables)

32 组织属性到tblinfo信息中

staticvoid

flagInhAttrs(DumpOptions*dopt, TableInfo *tblinfo, int numTables)

34 获取索引

void

getIndexes(Archive*fout, TableInfo tblinfo[], int numTables)

35 获取约束

void

getConstraints(Archive*fout, TableInfo tblinfo[], int numTables)

36 获取触发器

void

getTriggers(Archive*fout, TableInfo tblinfo[], int numTables)

37 获取规则

RuleInfo*

getRules(Archive*fout, int *numRules)

38 pg_policy策略

void

getPolicies(Archive*fout, TableInfo tblinfo[], int numTables)

40 获取分区主表定义信息

void

getTablePartitionKeyInfo(Archive*fout, TableInfo *tblinfo, int numTables)

 

表对象信息结构:

typedefstruct _tableInfo

{

       /*

        *These fields are collected for every table in the database.

        */

       DumpableObject dobj;

       char    *rolname;         /*name of owner, or empty string */

       char    *relacl;

       char    *rrelacl;

       char    *initrelacl;

       char    *initrrelacl;

       char        relkind;

       char        relpersistence;/* relation persistence */

       bool        relispopulated;/* relation is populated */

       char        relreplident;    /* replica identifier */

       char    *reltablespace;  /* relation tablespace */

       char    *reloptions;             /*options specified by WITH (...) */

       char    *checkoption;   /* WITH CHECK OPTION, if any */

       char    *toast_reloptions;            /* WITH options for the TOAST table */

       bool        hasindex;        /* does it have any indexes? */

       bool        hasrules;         /* does it have any rules? */

       bool        hastriggers;     /* does it have any triggers? */

       bool        rowsec;                 /* is row security enabled? */

       bool        forcerowsec;   /* is row security forced? */

       bool        hasoids;          /* does it have OIDs? */

       uint32            frozenxid;              /* table's relfrozenxid */

       uint32            minmxid;       /* table's relminmxid */

       Oid                toast_oid;       /* toast table's OID, or 0 if none */

       uint32            toast_frozenxid;     /* toast table's relfrozenxid, if any */

       uint32            toast_minmxid;      /* toast table's relminmxid */

       int                 ncheck;                 /* # of CHECK expressions */

       char    *reloftype;        /* underlying type for typed table */

       /* these two are set only if table is asequence owned by a column: */

       Oid                owning_tab;           /* OID of table owning sequence */

       int                 owning_col;           /* attr # of column owning sequence*/

       int                 relpages;         /* table's size in pages (frompg_class) */

 

       bool        interesting;     /* true if need to collect more data */

       bool        dummy_view;        /* view's real definition must bepostponed */

       bool        postponed_def;       /* matview must be postponed intopost-data */

 

       /*

        *These fields are computed only if we decide the table is interesting

        *(it's either a table to dump, or a direct parent of a dumpable table).

        */

       int                 numatts;         /* number of attributes */

       char   **attnames;        /*the attribute names */

       char   **atttypnames;   /* attribute type names */

       int             *atttypmod;             /*type-specific type modifiers */

       int             *attstattarget;    /* attribute statistics targets */

       char    *attstorage;              /*attribute storage scheme */

       char    *typstorage;             /*type storage scheme */

       bool    *attisdropped;   /* true if attr is dropped; don't dump it */

       int             *attlen;                   /*attribute length, used by binary_upgrade */

       char    *attalign;          /*attribute align, used by binary_upgrade */

       bool    *attislocal;        /*true if attr has local definition */

       char   **attoptions;             /*per-attribute options */

       Oid            *attcollation;    /* per-attribute collation selection */

       char   **attfdwoptions; /* per-attribute fdw options */

       bool    *notnull;          /*NOT NULL constraints on attributes */

       bool    *inhNotNull;           /*true if NOT NULL is inherited */

       struct _attrDefInfo **attrdefs;              /* DEFAULT expressions */

       struct _constraintInfo *checkexprs; /*CHECK constraints */

       char    *partkeydef;            /*partition key definition */

 

       /*

        *Stuff computed only for dumpable tables.

        */

       int                 numParents;           /* number of (immediate) parenttables */

       struct _tableInfo **parents;   /* TableInfos of immediate parents */

       struct _tableDataInfo *dataObj;            /* TableDataInfo, if dumping itsdata */

       int                 numTriggers;  /* number of triggers for table */

       struct _triggerInfo *triggers;         /* array of TriggerInfo structs */

       struct _tableInfo *partitionOf;      /* TableInfo for the partition parent */

       char    *partitiondef;           /* partition key definition */

}TableInfo;

3.9 、查找需要备份数据的对象

 

当前节点完成需要备份数据的对象整理,主要数据对象通过遍历tblinfo数组信息获取,使用TableDataInfo结构保存需要备份数据的对象,不同的对象类型其objtype不一致。

 

TableDataInfo结构定义:

typedefstruct _tableDataInfo

{

       DumpableObject dobj;

       TableInfo *tdtable;             /* link totable to dump */

       bool        oids;              /* include OIDs in data? */

       char    *filtercond;             /*WHERE condition to limit rows dumped */

}TableDataInfo;

 

不需要备份数据的对象:

1 --exclude-table-data 参数指定的表对象不需要备份数据

2 视图对象不需要备份数据

3 外部表对象不需要备份数据

4 分区主表不需要备份数据

5 unlogged permanent table 表对象并设置了 --no-unlogged-table-data不需要备份数据。

 

Objtype 类型处理:

1 雾化视图 dobj.objType =DO_REFRESH_MATVIEW

2 序列dobj.objType =DO_SEQUENCE_SET

3 其它dobj.objType =DO_TABLE_DATA

 

入口函数:

static void

getTableData(DumpOptions *dopt,TableInfo *tblinfo,int numTables, bool oids, charrelkind)

3.10 、排序对象数组

获取系统所有对象后,所有对象存放在DumpableObject **dobjs数组当中(保存对象地址),在每个对象创建前可能会依赖于其它对象,因此在处理对象时需要按照一定的顺序。

 

备份时排序通过两种方式完成:

 1 对象类型->模式名->对象名->对象oid

2 对于依赖其它对象的对象,被依赖的对象将优先处理。

 

通过对象类型排序:

1 对象类型排序顺序

   在对象数据生成时,每种对象定义对应的objtype,然后通过objtype作为下标定义其排序的优先顺序,objtype定义参考DumpableObjectType。

优先顺序定义:

staticconst 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_RULE */

       30,                                             /* DO_TRIGGER */

       27,                                             /*DO_CONSTRAINT */

       31,                                             /*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 */

       34,                                             /*DO_REFRESH_MATVIEW */

       35                                              /*DO_POLICY */

};

 

2 objtype 一致时,优先根据模式名进行排序

cmpval = strcmp(obj1->namespace->dobj.name,

                       obj2->namespace->dobj.name)

 

3 模式名一致时 ,优先排序对象名

cmpval = strcmp(obj1->name,obj2->name);

 

4 模式名一致时,针对函数,操作运算符,对象属性等 分别根据参数类型,操作符类型,属性对象的顺序(num)进行排序

5 其它情况优先参考oid大小顺序。

 

排序入口函数:

staticint

DOTypeNameCompare(constvoid *p1, const void *p2)

 

 

通过依赖进行排序:

 

排序入口函数

staticbool

TopoSort(DumpableObject**objs,

               int numObjs,

               DumpableObject **ordering,             /* output argument */

               int *nOrdering)           /* output argument */

3.11 、备份encoding,stdstring

3.12 、备份数据库

 如果参数-n ,-t参数没有设置并且-a参数没有设置,生成创建数据库语法加入到输出链表中(输出链表在3.13中介绍)。

static voiddumpDatabase(Archive *fout)

 

3.13 、备份对象以及数据

对象备份根据前面获取到的对象信息,按照对象本身的性质生成对象创建语法,对象数据备份有copy 方式和insert语法方式,当设定参数--inserts 时,备份的数据以insert 语法的形式输出,否则以copy的形式输出。

 

对象备份和数据备份同样以DumpableObject的方式保存在对象数组当中,依次遍历排好序的对象,然后根据定义的objType 类型,按照类型分别处理对象的输出形式。

 

   从上文中知道NamespaceInfo,ExtensionInfo等结构都继承于DumpableObject结构,以下处理时能按照需要的结构类型进行转换。处理逻辑如下:

staticvoid

dumpDumpableObject(Archive*fout, DumpableObject *dobj)

       switch (dobj->objType)

       {

              case DO_NAMESPACE:

                     dumpNamespace(fout,(NamespaceInfo *) dobj);

                     break;

              case DO_EXTENSION:

                     dumpExtension(fout,(ExtensionInfo *) dobj);

                     break;

              case DO_TYPE:

                     dumpType(fout, (TypeInfo *)dobj);

                     break;

              case DO_SHELL_TYPE:

                     dumpShellType(fout,(ShellTypeInfo *) dobj);

                     break;

              case DO_FUNC:

                     dumpFunc(fout, (FuncInfo *)dobj);

                     break;

              case DO_AGG:

                     dumpAgg(fout, (AggInfo *)dobj);

                     break;

              case DO_OPERATOR:

                     dumpOpr(fout, (OprInfo *)dobj);

                     break;

              case DO_ACCESS_METHOD:

                     dumpAccessMethod(fout,(AccessMethodInfo *) dobj);

                     break;

              case DO_OPCLASS:

                     dumpOpclass(fout,(OpclassInfo *) dobj);

                     break;

              case DO_OPFAMILY:

                     dumpOpfamily(fout,(OpfamilyInfo *) dobj);

                     break;

              case DO_COLLATION:

                     dumpCollation(fout,(CollInfo *) dobj);

                     break;

              case DO_CONVERSION:

                     dumpConversion(fout,(ConvInfo *) dobj);

                     break;

              case DO_TABLE:

                     dumpTable(fout, (TableInfo*) dobj);

                     break;

              case DO_ATTRDEF:

                     dumpAttrDef(fout,(AttrDefInfo *) dobj);

                     break;

              case DO_INDEX:

                     dumpIndex(fout, (IndxInfo*) dobj);

                     break;

              case DO_REFRESH_MATVIEW:

                     refreshMatViewData(fout,(TableDataInfo *) dobj);

                     break;

              case DO_RULE:

                     dumpRule(fout, (RuleInfo *)dobj);

                     break;

              case DO_TRIGGER:

                     dumpTrigger(fout,(TriggerInfo *) dobj);

                     break;

              case DO_EVENT_TRIGGER:

                     dumpEventTrigger(fout,(EventTriggerInfo *) dobj);

                     break;

              case DO_CONSTRAINT:

                     dumpConstraint(fout,(ConstraintInfo *) dobj);

                     break;

              case DO_FK_CONSTRAINT:

                     dumpConstraint(fout,(ConstraintInfo *) dobj);

                     break;

              case DO_PROCLANG:

                     dumpProcLang(fout,(ProcLangInfo *) dobj);

                     break;

              case DO_CAST:

                     dumpCast(fout, (CastInfo *)dobj);

                     break;

              case DO_TRANSFORM:

                     dumpTransform(fout,(TransformInfo *) dobj);

                     break;

              case DO_SEQUENCE_SET:

                     dumpSequenceData(fout,(TableDataInfo *) dobj);

                     break;

              case DO_TABLE_DATA:

                     dumpTableData(fout,(TableDataInfo *) dobj);

                     break;

              case DO_DUMMY_TYPE:

                     /* table rowtypes and arraytypes are never dumped separately */

                     break;

              case DO_TSPARSER:

                     dumpTSParser(fout,(TSParserInfo *) dobj);

                     break;

              case DO_TSDICT:

                     dumpTSDictionary(fout,(TSDictInfo *) dobj);

                     break;

              case DO_TSTEMPLATE:

                     dumpTSTemplate(fout,(TSTemplateInfo *) dobj);

                     break;

              case DO_TSCONFIG:

                     dumpTSConfig(fout,(TSConfigInfo *) dobj);

                     break;

              caseDO_FDW:

                     dumpForeignDataWrapper(fout,(FdwInfo *) dobj);

                     break;

              case DO_FOREIGN_SERVER:

                     dumpForeignServer(fout,(ForeignServerInfo *) dobj);

                     break;

              case DO_DEFAULT_ACL:

                     dumpDefaultACL(fout,(DefaultACLInfo *) dobj);

                     break;

              case DO_BLOB:

                     dumpBlob(fout, (BlobInfo *)dobj);

                     break;

              case DO_BLOB_DATA:

                     if (dobj->dump &DUMP_COMPONENT_DATA)

                            ArchiveEntry(fout,dobj->catId, dobj->dumpId,

                                                  dobj->name, NULL, NULL, "",

                                                  false, "BLOBS", SECTION_DATA,

                                                  "", "", NULL,

                                                  NULL, 0,

                                                  dumpBlobs, NULL);

                     break;

              case DO_POLICY:

                     dumpPolicy(fout,(PolicyInfo *) dobj);

                     break;

              case DO_PRE_DATA_BOUNDARY:

              case DO_POST_DATA_BOUNDARY:

                     /* never dumped, nothing todo */

                     break;

       }

}

 

组织好的语法使用双向链表存储,链表头在ArchiveHandle结构中进行声明,每处理一个对象,判别dobj.dump值,处理是否需要备份逻辑,然后将需要备份的对象添加到链表当中,输出时从链表中获取。

链表结构:

struct_tocEntry

{

       struct _tocEntry *prev;

       struct _tocEntry *next;

       CatalogId catalogId; 

       DumpId         dumpId;

       teSection section;

       bool        hadDumper;           /* Archiver was passed a dumperroutine (used

                                                         * in restore) */

       char    *tag;                /*index tag */

       char    *namespace;            /*null or empty string if not in a schema */

       char    *tablespace;             /*null if not in a tablespace; empty string

                                                         * means use database default */

       char    *owner;

       bool        withOids;       /* Used only by "TABLE" tags */

       char    *desc;

       char    *defn;

       char    *dropStmt;

       char    *copyStmt;

       DumpId     *dependencies;  /* dumpIds of objects this one depends on */

       int                 nDeps;                  /* number of dependencies */

 

       DataDumperPtr dataDumper; /* Routine to dump data for object */

       void    *dataDumperArg;    /* Arg for above routine */

       void    *formatData;           /*TOC Entry data specific to file format */

 

       /* working state while dumping/restoring*/

       teReqs            reqs;              /* do we need schema and/or dataof object */

       bool        created;          /* set for DATA member if TABLE wascreated */

 

       /* working state (needed only forparallel restore) */

       struct _tocEntry *par_prev; /* list linksfor pending/ready items; */

       struct _tocEntry *par_next; /* these areNULL if not in either list */

       int                 depCount;              /* number of dependencies not yetrestored */

       DumpId     *revDeps;         /*dumpIds of objects depending on this one */

       int                 nRevDeps;             /* number of such dependencies */

       DumpId     *lockDeps;              /*dumpIds of objects this one needs lock on */

       int                 nLockDeps;           /* number of such dependencies */

};

 

链表输出入库函数:

void

ArchiveEntry(Archive*AHX,   //ArchiveHandle 备份输出总结构地址

                      CatalogId catalogId,// 对象id,

 DumpId dumpId, //对象数组下表

                      const char *tag,//对象名

                      const char *namespace,//对象所属模式

                      const char *tablespace,//表空间

                      const char *owner, //用户名

boolwithOids,//是否备份oid

                      const char *desc,//备份对象的类型名

 teSection section,// teSection

                      const char *defn,//对象创建语法

                      const char *dropStmt, //对象清除语法

constchar *copyStmt,//对象数据备份语法

                      const DumpId *deps, int nDeps,

                      DataDumperPtr dumpFn, void *dumpArg)

3.14 、输出备份文件

    备份文件的输出根据备份参数设置的不同,使用函数指针,实现在统一过程当中,实现不同文件类型的操作,指针的初始化在3.3 节中实现:

   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);

       }

 

其中InitArchiveFmt_Custom 在pg_backup_custom.c文件中实现,   InitArchiveFmt_Null 在pg_backup_null.c中实现,InitArchiveFmt_Directory在 pg_backup_directory.c中实现 ,InitArchiveFmt_Tar 在pg_backup_tar.c中实现。

1 普通文本格式文件生成在

Void  RestoreArchive(Archive *AHX) 函数中完成,依次输出注释,环境设置,对象生成语法到文件当中。

2 其它格式输出按照占位的方式输出 ,除了输出文件头和文件内容外,其它不同操作实现各不相同  参考如下:

 

Void CloseArchive(Archive *AHX) 函数中完成,实际通过函数指针调用各自格式的函数。除archNull格式,其它文件输出都包含文件头和文件内容两部分。具体参考各自文件的staticvoid

_CloseArchive(ArchiveHandle *AH) 函数。

 

  文件头输出格式一致,包含PGDMP,版本信息,备份时间等信息,具体如下:

void

WriteHead(ArchiveHandle*AH)

{

       struct tm  crtm;

 

       (*AH->WriteBufPtr) (AH,"PGDMP", 5);          /* Magiccode */

       (*AH->WriteBytePtr) (AH,ARCHIVE_MAJOR(AH->version));

       (*AH->WriteBytePtr) (AH,ARCHIVE_MINOR(AH->version));

       (*AH->WriteBytePtr) (AH,ARCHIVE_REV(AH->version));

       (*AH->WriteBytePtr) (AH,AH->intSize);

       (*AH->WriteBytePtr) (AH,AH->offSize);

       (*AH->WriteBytePtr) (AH,AH->format);

       WriteInt(AH, AH->compression);

       crtm =*localtime(&AH->createDate);

       WriteInt(AH, crtm.tm_sec);

       WriteInt(AH, crtm.tm_min);

       WriteInt(AH, crtm.tm_hour);

       WriteInt(AH, crtm.tm_mday);

       WriteInt(AH, crtm.tm_mon);

       WriteInt(AH, crtm.tm_year);

       WriteInt(AH, crtm.tm_isdst);

       WriteStr(AH, PQdb(AH->connection));

       WriteStr(AH, AH->public.remoteVersionStr);

       WriteStr(AH, PG_VERSION);

}

 

文件内容输出:

for (te =AH->toc->next;te != AH->toc;te = te->next)

       {

              if ((te->reqs & (REQ_SCHEMA |REQ_DATA | REQ_SPECIAL)) == 0)

                     continue;

 

              WriteInt(AH,te->dumpId);

              WriteInt(AH,te->dataDumper ? 1 :0);

 

              /* OIDis recorded as a string for historical reasons */

              sprintf(workbuf,"%u", te->catalogId.tableoid);

              WriteStr(AH,workbuf);

              sprintf(workbuf,"%u", te->catalogId.oid);

              WriteStr(AH,workbuf);

 

              WriteStr(AH,te->tag);

              WriteStr(AH,te->desc);

              WriteInt(AH,te->section);

              WriteStr(AH,te->defn);

              WriteStr(AH,te->dropStmt);

              WriteStr(AH,te->copyStmt);

              WriteStr(AH,te->namespace);

              WriteStr(AH,te->tablespace);

              WriteStr(AH,te->owner);

              WriteStr(AH,te->withOids ? "true" : "false");

 

              /* Dumplist of dependencies */

              for (i = 0;i < te->nDeps;i++)

              {

                     sprintf(workbuf,"%d", te->dependencies[i]);

                     WriteStr(AH,workbuf);

              }

              WriteStr(AH,NULL);          /*Terminate List */

 

              if (AH->WriteExtraTocPtr)

                     (*AH->WriteExtraTocPtr) (AH,te);

       }

 







pg_dump相关命令参数记录 pg_dump是用于备份一种PostgreSQL数据库的工具。即使数据库正在被并发使用,它也能创建一致的备份。pg_dump不阻塞其他用户访问数据库(读取或写入)。 pg_dump只转储单个数据库。要备份一个集簇中 对于所有数据库公共的全局对象(例如角色和表空间),应使用 pg_dumpall。 转储可以被输出到脚本或归档文件格式。脚本转储是包含 SQL 命令的纯文本文件,它们可以用来重构数据库到... 阅读详情

相关推荐

PostgreSQL数据库备份还原全攻略

文章目录前言一、逻辑备份1.pg_dump工具2.pg_dumpall工具二、逻辑备份还原三、连续归档备份四、连续归档恢复总结 前言 逻辑备份 即SQL转储方式,使用pg_dump和pg_dumpall进行备份。逻辑备份在恢复时,介于逻辑备份与故障时间点之间的数据难以恢复,所以逻辑备份适用于留存某个时间点的备份或进行跨平台跨版本的数据迁移。 文件系统级备份 即拷贝数据文件的完整目录,备份时需要关闭数据库。恢复数据库时,只需将数据目录复制到原来的位置。该方式实际工作中很少使用。 连续归档 该方式是把一个

ma286388309的博客 1万+

PostgreSql pg_dump用法

pg_dump [connection-option...] [option...] [dbname] pg_dump 连接选项参数如下: -h host 或 --host=host:指定运行服务器的主机名。 -p port 或 --port=port:监听端口号,默认端口为5432。 -U username 或 --username=username:指定要连接的用户名。 -w 或 --no-password:从不提示密码,该选项常用于后台脚本中。 -W 或 --password:强制 pg_dump

脑子进水养啥鱼?的博客 1万+

如何使用 pg_dump 和 pg_dumpall 进行PostgreSQL数据库备份

使用 的用户,pg_dump 和 pg_dumpall 是两种常用的备份工具。本文将详细介绍如何使用这两种工具进行数据库备份。首先,确保你已经安装了 PostgreSQL,并且 pg_dump 和 pg_dumpall 命令可用。你可以通过以下命令检查: 如果没有安装 PostgreSQL,可以参考PostgreSQL16.3基于CentOS7.9源码安装步骤 这将备份 database_name 数据库到 backup.sql 文件。你

分享关于Java编程、数据库管理和信息安全方面的最佳实践 2677

PostgreSQL逻辑备份pg_dump使用及其原理解析

PostgreSQL逻辑备份pg_dump使用及其原理解析

Baiyi_destroyer的博客 4260

PostgreSQL源码分析——pg_control

pg_control是PostgreSQL中一个很重要的文件,我们之前讲到过PostgreSQL的启动过程,启动过程中很重要的一项工作就是故障恢复,启动startup进程,回放WAL日志进行故障恢复,而从哪里开始进行回放呢?这个位置的保存一定是在磁盘中,而不是在内存中,假设数据库因故障崩溃,内存中的数据会丢失,所以,只有checkpointer进程在做checkpoint操作时不断的更新pg_control文件,使之持久化保存,数据库启动进行故障恢复时,读取该文件,获得故障恢复的起始位置。

内核思考 1330

别再用dump/restore了!用pg_upgrade把PostgreSQL从9.3升到10,我踩过的坑都在这

本文详细介绍了使用pg_upgrade工具将PostgreSQL从9.3版本升级到10版本的实战经验,包括升级前的关键决策、环境准备中的隐藏陷阱、升级执行时的实战技巧以及升级后的关键验证。通过对比dump/restore方法,pg_upgrade在减少停机时间和存储空间需求方面表现出显著优势,特别适合生产环境中的大规模数据库升级。

weixin_30752699的博客 425

PostgreSQL源码分析pg_dump(一) pg_dump总体结构预览

pg_dump清晰的模块化架构完善的依赖关系处理灵活的扩展性设计强大的并行处理能力。

weixin_43164251的博客 1007

PG备份管理工具pg_probackup

文章目录一、pg_probackup概述二、安装部署2.1 源码安装2.2 rpm包安装部署三、常用命令四、工具使用4.1 初始化配置4.2 数据备份(全备+增备)4.3 数据恢复 一、pg_probackup概述 pg_probackup 是一款免费的postgres数据库集群备份工具,与其他备份工具相比,它主要有如下一些优势: 提供增量备份,增量备份一定程度上可以节省磁盘空间的使用并且减少备份时间消耗 可通过全量备份+增量备份进行增量恢复 无需通过实际的数据恢复操作验证备份文件是否有效 Verific

三思的博客 3149

PostgreSQL源码分析-PG_dump:表读取数据模块

【代码】PostgreSQL源码分析-PG_dump:表读取数据模块。

weixin_43164251的博客 794

【Excel VBA 编程】表格内自动生成进度条

在表格中生成进度条,进度条需要自适应单元格的宽度,根据不同进度区间变换颜色,并且按照进度数据大小显示其长短

wei1019的专栏 1521

BSW: Dcm模块配置--28服务

这个章节讲解下UDS中的28服务(Communcation Control)的配置,顾名思义,对当前ECU的通讯状态进行变更,主要设置应用报文,网络管理报文的收发控制,通常应用在刷写APP软件时,降低总线负载。这里首先要提醒的一点是,28服务几乎不需要手写代码,只有在客户需求要求前置条件不满足时报特定NRC时才需要填充代码。实际配置中主要涉及的模块有DCM,BSWM,ComM,RTE.2.BswM模块的配置。3.ComM模块的配置。1.DCM模块的配置。

Forever_Oct的博客 3086

postgresql pg_dump源码阅读--doing

【代码】postgresql pg_dump源码阅读--doing。

weixin_41685257的博客 155

arcgis密度分析

密度分析 密度分析是指根据输入的要素数据集计算整个区域的数据集状况,从而产生一个连续的密度表面。通过计算密度,将每个采样点的值散布到整个研究区域,并获得输出栅格中每个像元的密度值。在 ArcGIS 中,分布密度的计算方法有点密度分析、线密度分析和核密度分析三种。 1.点密度分析 导入实验数据居民点图层和道路图层 在自定义里勾选空间分析模块Spatial Analyst 点击空间分析工具中密度分析内的点密度分析, 参数设置如下,其中输出像元大小表示输出栅格数据集的像元大小。值越小.

Jasenjane的博客 2万+

PgSQL · 源码分析· pg_dump分析

PostgreSQL本身提供了逻辑导出工具pg_dumpall和pg_dump,其中pg_dumpall导出所有的数据库,pg_dump导出单个数据库,两个工具的用法和参数不再详细介绍,本文从代码层面上对此过程进行分析。 概括地说,逻辑导出要干的事情就是连接对应数据库,读出各个数据库对象的定义和数据,此外还包括comment、服务器配置和权限控制等等,...

weixin_34290631的博客 297

Cadence电路原理图全部变成黄色如何解决?

Cadence电路原理图全部变成黄色如何解决?现象:解决方法: 最近用cadence仿真锁相环,拷贝师哥的library后打开,发现schematic中全部变成了黄色,但可以正常修改元件参数,正常仿真。仅仅影响使用效果,看起来超级难受。 现象: 1.电路元件及连线全部变为黄色 2.可以正常修改参数,电路ADE仿真 如下图所示: 解决方法: 重新导入display.drf文件,步骤如下: tool——Display Resource Manager,截图如下 完成上述步骤,显示如下界面,选择Merge选项

virtuoso~晓晓 1万+

下载MNIST数据集并使用python将数据转换成NumPy数组(源码解析)

下载MNIST数据集并使用python将数据转换成NumPy数组首先来分析init_mnist函数接下来继续分析load_mnist函数实现数据集转换的python脚本的代码显示MNIST图像并确认数据 下载MNIST数据集并将数据转换成NumPy数组的Python脚本里面最重要的就是load_mnist函数,其他项目想要调用数据集的话,就可以调用load_mnist函数,得到一个字典类型的数据,字典的值是一个Numpy数组。 这些过程是如何实现的,现在开始逐字逐句分析源码: 在load_mnist函数中第

及时总结 4269

循序渐进丨MogDB 中 gs_dump 数据库导出工具源码概览

添加schema时,schema_include_patterns参数来自于命令行参数-n,在expand_schema_name_patterns函数中,通过简单的查询pg_namespace视图,将schema的oid 添加到列表中。而添加表时table_include_patterns和table_exclude_patterns分别来自命令行参数-t 和-T,通过查询pg_class 和 pg_namespace,将oid 添加分别添加到导出类别和排除列表中。备份期间对数据库和表如何加锁?

weixin_54551388的博客 986

复现论文《基于Retinex理论和深度学习的低照度图像增强算法研究》

本研究提出两种基于Retinex理论和深度学习的低照度图像增强算法。第一种算法在HSV色彩空间中进行处理,采用Res2Block和CBAM-Res2block模块增强多尺度特征表示;第二种算法使用多尺度残差U型网络结构。复现代码展示了Res2Block、CBAM注意力机制等核心模块的实现,包括多尺度特征提取、通道和空间注意力机制。实验结果表明,所提算法能有效解决低照度图像存在的亮度低、对比度不足、颜色失真和细节丢失等问题,显著提升图像质量。

max500600的博客 390

pgcopydb vs 传统pg_dump:为什么它能让数据库迁移速度提升300%?

pgcopydb 是一款针对 PostgreSQL 数据库迁移的高性能工具,通过创新的并发处理机制,相比传统的 pg_dump/pg_restore 组合,能够将数据库迁移速度提升高达 300%。无论是大型生产环境还是频繁的开发测试环境迁移,pgcopydb 都能显著缩短迁移时间,降低业务中断风险。 ## 传统迁移方案的痛点:为何 pg_dump 不再够用? PostgreSQL 自带的 pg

gitblog_00408的博客 1027

STM32F407上优化CAN总线通信(500kbps速率,多终端系统)需要从硬件设计、软件配置和实时性能三个方面进行综合优化

STM32F407上优化CAN总线通信(500kbps速率,多终端系统)需要从硬件设计、软件配置和实时性能三个方面进行综合优化

a_zxswer的博客 383

汽车LIN总线(3) -- 协议层:帧的类型

主要介绍LIN协议层中帧的类型,介绍中加入一点自己的理解(带下划线的是,其余是官方资料)。

晴朗luo的博客 890

spatie/db-dumper源码解析:如何用PHP优雅调用mysqldump和pg_dump

spatie/db-dumper是一个功能强大的PHP库,它提供了一种优雅的方式来调用mysqldump、pg_dump等数据库备份工具,帮助开发者轻松实现数据库内容的导出功能。通过这个库,即使是新手开发者也能快速掌握数据库备份的实现方法。 ## 核心架构设计:面向对象的数据库备份解决方案 spatie/db-dumper采用了抽象基类与具体实现类相结合的设计模式,这种架构让代码更具可维护性和

gitblog_00606的博客 417

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

postgresql pg_upgrade源码阅读--doing

pg_upgrade升级时支持如下参数。

weixin_41685257的博客 238

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Android dump渲染和合成图层GraphicBuffer指南

      Android dump渲染和合成图层GraphicBuffer指南 引言   博客停更很久了,提起笔来渐感生疏啊!看来,还是得抽出时间来更新更新啊!好了,感慨也发完了,是时候切入正题了。本篇博客将主要详细介绍如何dump Android渲染和合成图层GraphicBuffer,并通过YUV软件查看流程!通过本篇博客,读者将会至少学会如下两点: 通过dump Android渲染图层GraphicBuffer,查看Android渲染结果是否正确 通过dump Android合成图层Graph

IT先森 9104

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

上一篇: postgresql内核语法解析器详解
下一篇: postgresql中如何新增加一个SysCache
postgres20
博客等级 码龄10年 100粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值