summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavan Deolasee2017-04-18 06:57:06 +0000
committerPavan Deolasee2017-05-05 04:59:34 +0000
commit69fba376ab646b51e9645b302bc28b2c02d6779a (patch)
tree6e26be6b15a83cf26239402d8fad9987fc191f1f
parent5e6562f0edc534d668639694590f2534fbb04a51 (diff)
Allow pg_dump to dump from PostgreSQL databases.
The current implementation could only dump from XL database, which is not ideal since we then need to use pg_dump/pg_dumpall from PG installation to dump PG database. We now check whether the remote server is running XL or PG and then acoordingly skip XL-specific dumps.
-rw-r--r--src/bin/pg_dump/pg_backup.h1
-rw-r--r--src/bin/pg_dump/pg_backup_db.c20
-rw-r--r--src/bin/pg_dump/pg_dump.c176
3 files changed, 121 insertions, 76 deletions
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
index 4afa92f5f6..82c3baa9f1 100644
--- a/src/bin/pg_dump/pg_backup.h
+++ b/src/bin/pg_dump/pg_backup.h
@@ -174,6 +174,7 @@ typedef struct Archive
char *remoteVersionStr; /* server's version string */
int remoteVersion; /* same in numeric form */
bool isStandby; /* is server a standby node */
+ bool isPostgresXL; /* is server a Postgres-XL node */
int minRemoteVersion; /* allowable range */
int maxRemoteVersion;
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
index d2a3de3c5d..d7e776071b 100644
--- a/src/bin/pg_dump/pg_backup_db.c
+++ b/src/bin/pg_dump/pg_backup_db.c
@@ -73,6 +73,26 @@ _check_database_version(ArchiveHandle *AH)
}
else
AH->public.isStandby = false;
+
+ /*
+ * Check if we are connected to a Postgres-XL node. We do a pretty basic
+ * check for existence of pgxc_class table in pg_catalog schema.
+ *
+ * We don't think there will be a XC/XL database running anything older
+ * than 9.1. So only look for server versions great than that.
+ */
+ if (remoteversion >= 90100)
+ {
+ res = ExecuteSqlQueryForSingleRow((Archive *) AH, "SELECT EXISTS "
+ "(SELECT 1 FROM pg_catalog.pg_class where relname = 'pgxc_class' "
+ "AND relnamespace = (SELECT oid FROM pg_namespace "
+ "WHERE nspname = 'pg_catalog'))");
+
+ AH->public.isPostgresXL = (strcmp(PQgetvalue(res, 0, 0), "t") == 0);
+ PQclear(res);
+ }
+ else
+ AH->public.isPostgresXL = false;
}
/*
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 83c2523408..03ed88732b 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -5294,9 +5294,7 @@ getTables(Archive *fout, int *numTables)
"d.refobjsubid AS owning_col, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
#ifdef PGXC
- "(SELECT pclocatortype from pgxc_class v where v.pcrelid = c.oid) AS pgxclocatortype,"
- "(SELECT pcattnum from pgxc_class v where v.pcrelid = c.oid) AS pgxcattnum,"
- "(SELECT string_agg(node_name,',') AS pgxc_node_names from pgxc_node n where n.oid in (select unnest(nodeoids) from pgxc_class v where v.pcrelid=c.oid) ) , "
+ "%s"
#endif
"array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
"CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
@@ -5395,6 +5393,11 @@ getTables(Archive *fout, int *numTables)
"WHERE c.relkind in ('%c', '%c', '%c', '%c', '%c', '%c') "
"ORDER BY c.oid",
username_subquery,
+ fout->isPostgresXL
+ ? "(SELECT pclocatortype from pgxc_class v where v.pcrelid = c.oid) AS pgxclocatortype,"
+ "(SELECT pcattnum from pgxc_class v where v.pcrelid = c.oid) AS pgxcattnum,"
+ "(SELECT string_agg(node_name,',') AS pgxc_node_names from pgxc_node n where n.oid in (select unnest(nodeoids) from pgxc_class v where v.pcrelid=c.oid) ) , "
+ : "",
RELKIND_SEQUENCE,
RELKIND_RELATION, RELKIND_SEQUENCE,
RELKIND_VIEW, RELKIND_COMPOSITE_TYPE,
@@ -5427,9 +5430,7 @@ getTables(Archive *fout, int *numTables)
"d.refobjsubid AS owning_col, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
#ifdef PGXC
- "(SELECT pclocatortype from pgxc_class v where v.pcrelid = c.oid) AS pgxclocatortype,"
- "(SELECT pcattnum from pgxc_class v where v.pcrelid = c.oid) AS pgxcattnum,"
- "(SELECT string_agg(node_name,',') AS pgxc_node_names from pgxc_node n where n.oid in (select unnest(nodeoids) from pgxc_class v where v.pcrelid=c.oid) ) , "
+ "%s"
#endif
"array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
"CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
@@ -5446,6 +5447,11 @@ getTables(Archive *fout, int *numTables)
"WHERE c.relkind in ('%c', '%c', '%c', '%c', '%c', '%c') "
"ORDER BY c.oid",
username_subquery,
+ fout->isPostgresXL
+ ? "(SELECT pclocatortype from pgxc_class v where v.pcrelid = c.oid) AS pgxclocatortype,"
+ "(SELECT pcattnum from pgxc_class v where v.pcrelid = c.oid) AS pgxcattnum,"
+ "(SELECT string_agg(node_name,',') AS pgxc_node_names from pgxc_node n where n.oid in (select unnest(nodeoids) from pgxc_class v where v.pcrelid=c.oid) ) , "
+ : "",
RELKIND_SEQUENCE,
RELKIND_RELATION, RELKIND_SEQUENCE,
RELKIND_VIEW, RELKIND_COMPOSITE_TYPE,
@@ -5478,9 +5484,7 @@ getTables(Archive *fout, int *numTables)
"d.refobjsubid AS owning_col, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
#ifdef PGXC
- "(SELECT pclocatortype from pgxc_class v where v.pcrelid = c.oid) AS pgxclocatortype,"
- "(SELECT pcattnum from pgxc_class v where v.pcrelid = c.oid) AS pgxcattnum,"
- "(SELECT string_agg(node_name,',') AS pgxc_node_names from pgxc_node n where n.oid in (select unnest(nodeoids) from pgxc_class v where v.pcrelid=c.oid) ) , "
+ "%s"
#endif
"array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
"CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
@@ -5497,6 +5501,11 @@ getTables(Archive *fout, int *numTables)
"WHERE c.relkind in ('%c', '%c', '%c', '%c', '%c', '%c') "
"ORDER BY c.oid",
username_subquery,
+ fout->isPostgresXL
+ ? "(SELECT pclocatortype from pgxc_class v where v.pcrelid = c.oid) AS pgxclocatortype,"
+ "(SELECT pcattnum from pgxc_class v where v.pcrelid = c.oid) AS pgxcattnum,"
+ "(SELECT string_agg(node_name,',') AS pgxc_node_names from pgxc_node n where n.oid in (select unnest(nodeoids) from pgxc_class v where v.pcrelid=c.oid) ) , "
+ : "",
RELKIND_SEQUENCE,
RELKIND_RELATION, RELKIND_SEQUENCE,
RELKIND_VIEW, RELKIND_COMPOSITE_TYPE,
@@ -5529,9 +5538,7 @@ getTables(Archive *fout, int *numTables)
"d.refobjsubid AS owning_col, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
#ifdef PGXC
- "(SELECT pclocatortype from pgxc_class v where v.pcrelid = c.oid) AS pgxclocatortype,"
- "(SELECT pcattnum from pgxc_class v where v.pcrelid = c.oid) AS pgxcattnum,"
- "(SELECT string_agg(node_name,',') AS pgxc_node_names from pgxc_node n where n.oid in (select unnest(nodeoids) from pgxc_class v where v.pcrelid=c.oid) ) , "
+ "%s"
#endif
"c.reloptions AS reloptions, "
"tc.reloptions AS toast_reloptions, "
@@ -5546,6 +5553,11 @@ getTables(Archive *fout, int *numTables)
"WHERE c.relkind in ('%c', '%c', '%c', '%c', '%c', '%c') "
"ORDER BY c.oid",
username_subquery,
+ fout->isPostgresXL
+ ? "(SELECT pclocatortype from pgxc_class v where v.pcrelid = c.oid) AS pgxclocatortype,"
+ "(SELECT pcattnum from pgxc_class v where v.pcrelid = c.oid) AS pgxcattnum,"
+ "(SELECT string_agg(node_name,',') AS pgxc_node_names from pgxc_node n where n.oid in (select unnest(nodeoids) from pgxc_class v where v.pcrelid=c.oid) ) , "
+ : "",
RELKIND_SEQUENCE,
RELKIND_RELATION, RELKIND_SEQUENCE,
RELKIND_VIEW, RELKIND_COMPOSITE_TYPE,
@@ -5915,9 +5927,12 @@ getTables(Archive *fout, int *numTables)
i_owning_tab = PQfnumber(res, "owning_tab");
i_owning_col = PQfnumber(res, "owning_col");
#ifdef PGXC
- i_pgxclocatortype = PQfnumber(res, "pgxclocatortype");
- i_pgxcattnum = PQfnumber(res, "pgxcattnum");
- i_pgxc_node_names = PQfnumber(res, "pgxc_node_names");
+ if (fout->isPostgresXL)
+ {
+ i_pgxclocatortype = PQfnumber(res, "pgxclocatortype");
+ i_pgxcattnum = PQfnumber(res, "pgxcattnum");
+ i_pgxc_node_names = PQfnumber(res, "pgxc_node_names");
+ }
#endif
i_reltablespace = PQfnumber(res, "reltablespace");
i_reloptions = PQfnumber(res, "reloptions");
@@ -5989,18 +6004,21 @@ getTables(Archive *fout, int *numTables)
tblinfo[i].owning_col = atoi(PQgetvalue(res, i, i_owning_col));
}
#ifdef PGXC
- /* Not all the tables have pgxc locator Data */
- if (PQgetisnull(res, i, i_pgxclocatortype))
+ if (fout->isPostgresXL)
{
- tblinfo[i].pgxclocatortype = 'E';
- tblinfo[i].pgxcattnum = 0;
- }
- else
- {
- tblinfo[i].pgxclocatortype = *(PQgetvalue(res, i, i_pgxclocatortype));
- tblinfo[i].pgxcattnum = atoi(PQgetvalue(res, i, i_pgxcattnum));
+ /* Not all the tables have pgxc locator Data */
+ if (PQgetisnull(res, i, i_pgxclocatortype))
+ {
+ tblinfo[i].pgxclocatortype = 'E';
+ tblinfo[i].pgxcattnum = 0;
+ }
+ else
+ {
+ tblinfo[i].pgxclocatortype = *(PQgetvalue(res, i, i_pgxclocatortype));
+ tblinfo[i].pgxcattnum = atoi(PQgetvalue(res, i, i_pgxcattnum));
+ }
+ tblinfo[i].pgxc_node_names = pg_strdup(PQgetvalue(res, i, i_pgxc_node_names));
}
- tblinfo[i].pgxc_node_names = pg_strdup(PQgetvalue(res, i, i_pgxc_node_names));
#endif
tblinfo[i].reltablespace = pg_strdup(PQgetvalue(res, i, i_reltablespace));
tblinfo[i].reloptions = pg_strdup(PQgetvalue(res, i, i_reloptions));
@@ -15534,39 +15552,42 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
}
#ifdef PGXC
- /* Add the grammar extension linked to PGXC depending on data got from pgxc_class */
- if (tbinfo->pgxclocatortype != 'E')
+ if (fout->isPostgresXL)
{
- /* N: DISTRIBUTE BY ROUNDROBIN */
- if (tbinfo->pgxclocatortype == 'N')
- {
- appendPQExpBuffer(q, "\nDISTRIBUTE BY ROUNDROBIN");
- }
- /* R: DISTRIBUTE BY REPLICATED */
- else if (tbinfo->pgxclocatortype == 'R')
+ /* Add the grammar extension linked to PGXC depending on data got from pgxc_class */
+ if (tbinfo->pgxclocatortype != 'E')
{
- appendPQExpBuffer(q, "\nDISTRIBUTE BY REPLICATION");
- }
- /* H: DISTRIBUTE BY HASH */
- else if (tbinfo->pgxclocatortype == 'H')
- {
- int hashkey = tbinfo->pgxcattnum;
- appendPQExpBuffer(q, "\nDISTRIBUTE BY HASH (%s)",
- fmtId(tbinfo->attnames[hashkey - 1]));
+ /* N: DISTRIBUTE BY ROUNDROBIN */
+ if (tbinfo->pgxclocatortype == 'N')
+ {
+ appendPQExpBuffer(q, "\nDISTRIBUTE BY ROUNDROBIN");
+ }
+ /* R: DISTRIBUTE BY REPLICATED */
+ else if (tbinfo->pgxclocatortype == 'R')
+ {
+ appendPQExpBuffer(q, "\nDISTRIBUTE BY REPLICATION");
+ }
+ /* H: DISTRIBUTE BY HASH */
+ else if (tbinfo->pgxclocatortype == 'H')
+ {
+ int hashkey = tbinfo->pgxcattnum;
+ appendPQExpBuffer(q, "\nDISTRIBUTE BY HASH (%s)",
+ fmtId(tbinfo->attnames[hashkey - 1]));
+ }
+ else if (tbinfo->pgxclocatortype == 'M')
+ {
+ int hashkey = tbinfo->pgxcattnum;
+ appendPQExpBuffer(q, "\nDISTRIBUTE BY MODULO (%s)",
+ fmtId(tbinfo->attnames[hashkey - 1]));
+ }
}
- else if (tbinfo->pgxclocatortype == 'M')
+ if (include_nodes &&
+ tbinfo->pgxc_node_names != NULL &&
+ tbinfo->pgxc_node_names[0] != '\0')
{
- int hashkey = tbinfo->pgxcattnum;
- appendPQExpBuffer(q, "\nDISTRIBUTE BY MODULO (%s)",
- fmtId(tbinfo->attnames[hashkey - 1]));
+ appendPQExpBuffer(q, "\nTO NODE (%s)", tbinfo->pgxc_node_names);
}
}
- if (include_nodes &&
- tbinfo->pgxc_node_names != NULL &&
- tbinfo->pgxc_node_names[0] != '\0')
- {
- appendPQExpBuffer(q, "\nTO NODE (%s)", tbinfo->pgxc_node_names);
- }
#endif
/* Dump generic options if any */
if (ftoptions && ftoptions[0])
@@ -16664,32 +16685,35 @@ dumpSequenceData(Archive *fout, TableDataInfo *tdinfo)
last = PQgetvalue(res, 0, 0);
called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0);
#ifdef PGXC
- /*
- * In Postgres-XC it is possible that the current value of a
- * sequence cached on each node is different as several sessions
- * might use the sequence on different nodes. So what we do here
- * to get a consistent dump is to get the next value of sequence.
- * This insures that sequence value is unique as nextval is directly
- * obtained from GTM.
- */
- resetPQExpBuffer(query);
- appendPQExpBufferStr(query, "SELECT pg_catalog.nextval(");
- appendStringLiteralAH(query, fmtId(tbinfo->dobj.name), fout);
- appendPQExpBuffer(query, ");\n");
- res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
+ if (fout->isPostgresXL)
+ {
+ /*
+ * In Postgres-XC it is possible that the current value of a
+ * sequence cached on each node is different as several sessions
+ * might use the sequence on different nodes. So what we do here
+ * to get a consistent dump is to get the next value of sequence.
+ * This insures that sequence value is unique as nextval is directly
+ * obtained from GTM.
+ */
+ resetPQExpBuffer(query);
+ appendPQExpBufferStr(query, "SELECT pg_catalog.nextval(");
+ appendStringLiteralAH(query, fmtId(tbinfo->dobj.name), fout);
+ appendPQExpBuffer(query, ");\n");
+ res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
- if (PQntuples(res) != 1)
- {
- write_msg(NULL, ngettext("query to get nextval of sequence \"%s\" "
- "returned %d rows (expected 1)\n",
- "query to get nextval of sequence \"%s\" "
- "returned %d rows (expected 1)\n",
- PQntuples(res)),
- tbinfo->dobj.name, PQntuples(res));
- exit_nicely(1);
- }
+ if (PQntuples(res) != 1)
+ {
+ write_msg(NULL, ngettext("query to get nextval of sequence \"%s\" "
+ "returned %d rows (expected 1)\n",
+ "query to get nextval of sequence \"%s\" "
+ "returned %d rows (expected 1)\n",
+ PQntuples(res)),
+ tbinfo->dobj.name, PQntuples(res));
+ exit_nicely(1);
+ }
- last = PQgetvalue(res, 0, 0);
+ last = PQgetvalue(res, 0, 0);
+ }
#endif
resetPQExpBuffer(query);