This is an automated email from the ASF dual-hosted git repository. tuhaihe pushed a commit to branch REL_2_STABLE in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit e9d1e4dee04bb983be8ba51459cd7431656080bf Author: Brent Doil <[email protected]> AuthorDate: Tue Jul 11 13:58:39 2023 -0400 Add getPartitionDefs function to pg_dump Currently, when backing up a GP5 or GP6 database, getTables will hold a lock on all partition tables in the database by calling `pg_get_partition_def` and `pg_get_partition_template_def` on each table, resulting in tables being locked that are not part of the backup set. This commit extracts the `pg_get_partition_def` and `pg_get_partition_template_def` function calls out of getTables and into getPartitionDefs. Now, only partition tables in the backup set will be included in calls to these functions. Authored-by: Brent Doil <[email protected]> --- src/bin/pg_dump/common.c | 2 + src/bin/pg_dump/pg_dump.c | 99 ++++++++++++++++++++++++++++++++++++++++------- src/bin/pg_dump/pg_dump.h | 1 + 3 files changed, 88 insertions(+), 14 deletions(-) diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c index 75872b4473b..e180479d6a7 100644 --- a/src/bin/pg_dump/common.c +++ b/src/bin/pg_dump/common.c @@ -161,6 +161,8 @@ getSchemaData(Archive *fout, int *numTablesPtr) pg_log_info("reading user-defined tables"); tblinfo = getTables(fout, &numTables); + getPartitionDefs(fout, tblinfo, numTables); + getOwnedSeqs(fout, tblinfo, numTables); pg_log_info("reading user-defined functions"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 791091870d3..2f9749cdffa 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -7072,8 +7072,6 @@ getTables(Archive *fout, int *numTables) int i_isivm; int i_isdynamic; int i_relstorage; - int i_partclause; - int i_parttemplate; /* * Find all the tables and table-like objects. @@ -7252,11 +7250,7 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "NULL AS partkeydef, " "0 AS ispartition," - "NULL AS partbound, " - "CASE WHEN pl.parlevel = 0 THEN " - "(SELECT pg_get_partition_def(c.oid, true, true)) END AS partclause, " - "CASE WHEN pl.parlevel = 0 THEN " - "(SELECT pg_get_partition_template_def(c.oid, true, true)) END as parttemplate "); + "NULL AS partbound "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7389,8 +7383,6 @@ getTables(Archive *fout, int *numTables) i_relstorage = PQfnumber(res, "relstorage"); i_parrelid = PQfnumber(res, "parrelid"); i_parlevel = PQfnumber(res, "parlevel"); - i_partclause = PQfnumber(res, "partclause"); - i_parttemplate = PQfnumber(res, "parttemplate"); if (dopt->lockWaitTimeout) { @@ -7478,11 +7470,7 @@ getTables(Archive *fout, int *numTables) atoi(PQgetvalue(res, i, i_parlevel)) > 0) tblinfo[i].parparent = false; else - { tblinfo[i].parparent = true; - tblinfo[i].partclause = pg_strdup(PQgetvalue(res, i, i_partclause)); - tblinfo[i].parttemplate = pg_strdup(PQgetvalue(res, i, i_parttemplate)); - } if (!tblinfo[i].parparent && tblinfo[i].parrelid != 0 && tblinfo[i].relstorage == 'x') { @@ -7768,7 +7756,7 @@ getPartitioningInfo(Archive *fout) "WHERE opcname = 'enum_ops' " "AND opcnamespace = 'pg_catalog'::regnamespace " "AND amname = 'hash') = ANY(partclass)"); - + res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); ntups = PQntuples(res); @@ -7790,6 +7778,89 @@ getPartitioningInfo(Archive *fout) destroyPQExpBuffer(query); } +/* + * getPartitionDefs + * get information about GPDB partition definitions on a dumpable table + */ + +void +getPartitionDefs(Archive *fout, TableInfo tblinfo[], int numTables) +{ + + PQExpBuffer query = createPQExpBuffer(); + PQExpBuffer tbloids = createPQExpBuffer(); + PGresult *res; + int ntups; + int i_oid; + int i_partclause; + int i_parttemplate; + + /* Only relevant for GP5/GP6 */ + if (fout->remoteVersion > GPDB6_MAJOR_PGVERSION) + return; + + /* + * We want to perform just one query against pg_class. + * However, we mustn't try to select every row of those catalogs and then + * sort it out on the client side, because some of the server-side functions + * we need would be unsafe to apply to tables we don't have lock on. + * Hence, we build an array of the OIDs of tables we care about + * (and now have lock on!), and use a WHERE clause to constrain which rows are selected. + */ + appendPQExpBufferChar(tbloids, '{'); + for (int i = 0; i < numTables; i++) + { + TableInfo *tbinfo = &tblinfo[i]; + + /* We're only interested in dumping the partition definition for parent partitions */ + if (!tbinfo->parparent) + continue; + + /* + * We can ignore uninteresting tables, i.e. tables that will not be dumped. + */ + if (!tbinfo->interesting) + continue; + + /* OK, we need info for this table */ + if (tbloids->len > 1) /* do we have more than the '{'? */ + appendPQExpBufferChar(tbloids, ','); + appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid); + } + + appendPQExpBufferChar(tbloids, '}'); + resetPQExpBuffer(query); + + appendPQExpBuffer(query, + "SELECT src.oid,\n" + "(SELECT pg_get_partition_def(src.oid, true, true)) AS partclause,\n" + "(SELECT pg_get_partition_template_def(src.oid, true, true)) AS parttemplate\n" + "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n", tbloids->data); + + res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); + + ntups = PQntuples(res); + + i_oid = PQfnumber(res, "oid"); + i_partclause = PQfnumber(res, "partclause"); + i_parttemplate = PQfnumber(res, "parttemplate"); + + for (int i = 0; i < ntups; i++) + { + TableInfo *tbinfo = findTableByOid(atooid(PQgetvalue(res, i, i_oid))); + if (tblinfo) + { + tbinfo->partclause = pg_strdup(PQgetvalue(res, i, i_partclause)); + tbinfo->parttemplate = pg_strdup(PQgetvalue(res, i, i_parttemplate)); + } + + } + PQclear(res); + + destroyPQExpBuffer(query); + destroyPQExpBuffer(tbloids); +} + /* * getIndexes * get information about every index on a dumpable table diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 71cf6866ebf..f26d764d5b6 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -776,6 +776,7 @@ extern void getSubscriptions(Archive *fout); /* START MPP ADDITION */ extern ExtProtInfo *getExtProtocols(Archive *fout, int *numExtProtocols); extern BinaryUpgradeInfo *getBinaryUpgradeObjects(void); +extern void getPartitionDefs(Archive *fout, TableInfo tblinfo[], int numTables); /* END MPP ADDITION */ #endif /* PG_DUMP_H */ --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
