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
二、不同格式的处理函数
-F, --format=c|d|t|p output file format (custom, directory, tar,plain text (default))
目前,pg_dump支持4种导出格式: