

背景

初始化和设置
包含必要的头文件并设置环境相关的配置。 定义各种宏和常量以进行操作。 声明全局变量和结构体用于处理用户输入、数据库连接和转储选项。

命令行参数解析

static void getopt_dump(int argc, char** argv, struct option options[], int* result)
{
int opt;
while ((opt = getopt_long(argc, argv, "abcCE:f:F:g:h:n:N:oOp:q:RsS:t:T:U:vwW:xZ:", options, NULL)) != -1)
{
switch (opt)
{
case 'h':
显示帮助信息
help(argv[0]);
exit(0);
case 'F':
设置格式
format = optarg;
break;
case 'p':
设置端口
port = optarg;
break;
其他选项处理
}
}
}

创建输出文件,注册清理机制


连接数据库
errorMessages = ConnectDatabase(fout, dbname, pghost, pgport, username, prompt_password, false);
if (errorMessages != NULL) {
(void)remove(filename);
GS_FREE(filename);
exit_horribly(NULL, "connection to database \"%s\" failed: %s ",
((dbname != NULL) ? dbname : ""), errorMessages);
}
if (CheckIfStandby(fout)) {
(void)remove(filename);
exit_horribly(NULL, "%s is not supported on standby or cascade standby\n", progname);
}
if (schemaOnly) {
ExecuteSqlStatement(fout, "set enable_hashjoin=off");
ExecuteSqlStatement(fout, "set enable_mergejoin=off");
ExecuteSqlStatement(fout, "set enable_indexscan=true");
ExecuteSqlStatement(fout, "set enable_nestloop=true");
}
* Turn off log collection parameters to improve execution performance */
ExecuteSqlStatement(fout, "set resource_track_level='none'");
find_current_connection_node_type(fout);
Get the database which will be dumped
if (NULL == dbname) {
ArchiveHandle* AH = (ArchiveHandle*)fout;
dbname = gs_strdup(PQdb(AH->connection));
}
if (NULL == instport) {
ArchiveHandle* AH = (ArchiveHandle*)fout;
instport = gs_strdup(PQport(AH->connection));
}
if ((use_role != NULL) && (rolepasswd == NULL)) {
get_role_password();
}
setup_connection(fout);
static void setup_connection(Archive* AH)
{
建立数据库连接
PGconn *conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, username, password);
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn));
exit(1);
}
AH->connection = conn;
}

开启事务



添加导出schema和表


static void expand_schema_name_patterns(
...
if (patterns->head == NULL) {
return; * nothing to do */
}
query = createPQExpBuffer();
for (cell = patterns->head; cell != NULL; cell = cell->next) {
appendPQExpBuffer(query, "SELECT oid FROM pg_catalog.pg_namespace n\n");
...
}
destroyPQExpBuffer(query);
}

static void expand_table_name_patterns(
Archive* fout, SimpleStringList* patterns, SimpleOidList* oidlists, bool isinclude)
{
...
query = createPQExpBuffer();
for (cell = patterns->head; cell != NULL; cell = cell->next) {
appendPQExpBuffer(query,
"SELECT c.oid"
"\nFROM pg_catalog.pg_class c"
"\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace"
"\nWHERE c.relkind in ('%c', '%c', '%c', '%c', '%c','%c', '%c', '%c')\n",
RELKIND_RELATION,
RELKIND_SEQUENCE,
RELKIND_LARGE_SEQUENCE,
RELKIND_VIEW,
RELKIND_MATVIEW,
RELKIND_CONTQUERY,
RELKIND_FOREIGN_TABLE,
RELKIND_STREAM);
...
}
destroyPQExpBuffer(query);
}

获取导出数据对象
tblinfo = getSchemaData(fout, &numTables);
if (fout->remoteVersion < 80400)
guessConstraintInheritance(tblinfo, numTables);
if (!schemaOnly) {
getTableData(tblinfo, numTables);
if (dataOnly)
getTableDataFKConstraints();
}
if (outputBlobs)
getBlobs(fout);

获取依赖和排序
//获取数据库对象的依赖关系。依赖关系用于确保在导出数据库对象时,它们之间的顺序是正确的。
getDependencies(fout);
boundaryObjs = createBoundaryObjects();
//获取所有已知的数据库对象。
getDumpableObjects(&dobjs, &numObjs);
addBoundaryDependencies(dobjs, numObjs, boundaryObjs);
...
sortDumpableObjects(dobjs, numObjs, boundaryObjs[0].dumpId, boundaryObjs[1].dumpId);

执行导出
for (i = 0; i < numObjs; i++) {
if (!dataOnly && dobjs[i]->dump && dobjs[i]->objType != DO_DUMMY_TYPE &&
dobjs[i]->objType != DO_PRE_DATA_BOUNDARY && dobjs[i]->objType != DO_POST_DATA_BOUNDARY) {
dumpObjNums++;
if (dumpObjNums % OUTPUT_OBJECT_NUM == 0)
write_msg(NULL,
"[%6.2lf%%] %d objects have been dumped.\n",
float((float(dumpObjNums * 100.0)) totalObjNums),
dumpObjNums);
}
dumpDumpableObject(fout, dobjs[i]);
}
static void dumpDumpableObject(Archive *fout, DumpableObject *dobj)
{
根据对象的类型进行处理
switch (dobj->objType)
{
case DO_TABLE:
dumpTable(fout, (TableInfo *) dobj);
break;
case DO_INDEX:
dumpIndex(fout, (IndxInfo *) dobj);
break;
case DO_VIEW:
dumpView(fout, (ViewInfo *) dobj);
break;
case DO_TRIGGER:
dumpTrigger(fout, (TriggerInfo *) dobj);
break;
其他对象类型
/ ... }
}
static void dumpTableData(Archive* fout, TableDataInfo* tdinfo)
{
...
if (!dump_inserts) {
/* Dump/restore using COPY */
dumpFn = dumpTableData_copy;
} else {
/* Restore using INSERT */
dumpFn = dumpTableData_insert;
}
...
testdb=# SELECT pl.pid, pl.virtualtransaction AS vxid, pl.locktype AS lock_type,pl.mode AS lock_mode, pl.granted,
CASE
WHEN pl.virtualxid IS NOT NULL AND pl.transactionid IS NOT NULL THEN pl.virtualxid || ' ' || pl.transactionid
WHEN pl.virtualxid::text IS NOT NULL
THEN pl.virtualxid
ELSE
pl.transactionid::text
END AS xid_lock, pc.relname,
pl.page, pl.tuple, pl.classid, pl.objid, pl.objsubid,ps.usename,ps.application_name,ps.query
FROM pg_locks pl LEFT OUTER JOIN pg_class pc ON (pl.relation = pc.oid) left join pg_stat_activity ps on ps.pid = pl.pid
WHERE pl.pid != pg_backend_pid();
pid | vxid | lock_type | lock_mode | granted | xid_lock | relname | page | tuple | classid | objid | objsubid | usename | application_name
| query
----------------+----------+------------+-----------------+---------+----------+---------+------+-------+---------+-------+----------+---------+------------------+----------------------------------------
47858921375488 | 17/15218 | relation | AccessShareLock | t | | cct | | | | | | test | gsql
| copy cct to '/home/test/city.bat';

导出资源


释放资源

关于作者
END
MogDB 是云和恩墨基于 openGauss 开源内核进行增强提升,推出的一款安稳易用的企业级关系型数据库。其具备金融级高可用和全密态计算的极致安全、面向多核处理器的极致性能、AI自诊断调优的极致智能能力,能够满足从核心交易到复杂计算的企业级业务需求。
访问官网了解更多:www.mogdb.io
产品兼容适配申请:partner@enmotech.com
进入交流群:Roger_database


文章转载自MogDB,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




