中关村能力建设网站,宝安网站设计,广州番禺网站建设公司,做字幕的网站一、原理分析
1、循环调用getopt_long解析命令行参数#xff0c;将参数保存到static DumpOptions dopt;中 2、判断参数是否相容#xff0c;不相容则退出#xff1a; options -s/--schema-only and -a/--data-only cannot be used togetheroptions -c/--clean and -a/--data…一、原理分析
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根据服务器版本号查询系统表读出对象的元数据信息
2malloc内存空间并将查询结果存放到对象的数据结构中TableInfo
3对于每条元数据信息调用selectDumpableTable标记需要导出的表如果-t指定导出表遍历该列表得到对应表并标记DUMP_COMPONENT_ALL-T指定删除表标记tbinfo-dobj.dump DUMP_COMPONENT_NONE
4dumpIdMap[dobj-dumpId] dobj;将导出表的元数据存放到dumpIdMap数组中
5在导出表上执行LOCK TABLE %s IN ACCESS SHARE MODE
6将所有元数据信息保存后执行SET statement_timeout 0保证语句不超时能够一直执行下去
9、调用getTableData函数获取表对应的数据。实际上并不是表真正数据而是为表数据建立一个“导出对象”将来导出时依据导出对象获取真是的数据再导出。虽然先把导出对象放到AH-toc链表上真正导出时导出数据不会占用大量内存空间但是针对这些元数据当表特别多的时候由于不到进程退出不释放内存占用内存还是非常可观的。
该函数调用makeTableDataInfo
1view、外部表、分区表字表从父表导出和unlogged permanent table不用导出
2判断该表是否制定导出时被排除
3malloc一个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;
4tdinfo-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_encodingUTF8;\nSET standard_conforming_stringon;SELECT pg_catalog.set_config(search_path,,false);\n
15、dumpDatabase导出本链接对应的目的数据库信息同样是newTocnewToc-defnCREATE DATABASE yzs WITH TEMPLATEtemplate0 ENCODINGUTF8 LC_COLLATEzh_CN.UTF-8 LC_CTYPEzh_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, --formatc|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是目录。
[postgreslocalhost ~]$ pg_dump --formatd yzs -f test
[postgreslocalhost ~]$ cd test
[postgreslocalhost 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中
[postgreslocalhost ~]$ pg_dump --formatp yzs -f test.sql
3以二进制格式输出
[postgreslocalhost ~]$ pg_dump --formatc -f test yzs
4以tar格式输出。与d格式不同在于多了一个restore.sql文件plain格式文件并将所有文件打包成一个文件
[postgreslocalhost ~]$ pg_dump --formatt -f test yzs
[postgreslocalhost ~]$ 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