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]

Reply via email to