summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorStephen Frost2017-03-06 22:04:29 +0000
committerStephen Frost2017-03-06 22:04:29 +0000
commit7f831f09bb85d93d99f55269479e4b6d105937f8 (patch)
tree0fa27f349b0f64877bbcfdc0d21e2249788f9be1 /src/bin
parent6987277619f218d4056178ac1d9c6d9ef8efc9c8 (diff)
pg_upgrade: Fix large object COMMENTS, SECURITY LABELS
When performing a pg_upgrade, we copy the files behind pg_largeobject and pg_largeobject_metadata, allowing us to avoid having to dump out and reload the actual data for large objects and their ACLs. Unfortunately, that isn't all of the information which can be associated with large objects. Currently, we also support COMMENTs and SECURITY LABELs with large objects and these were being silently dropped during a pg_upgrade as pg_dump would skip everything having to do with a large object and pg_upgrade only copied the tables mentioned to the new cluster. As the file copies happen after the catalog dump and reload, we can't simply include the COMMENTs and SECURITY LABELs in pg_dump's binary-mode output but we also have to include the actual large object definition as well. With the definition, comments, and security labels in the pg_dump output and the file copies performed by pg_upgrade, all of the data and metadata associated with large objects is able to be successfully pulled forward across a pg_upgrade. In 9.6 and master, we can simply adjust the dump bitmask to indicate which components we don't want. In 9.5 and earlier, we have to put explciit checks in in dumpBlob() and dumpBlobs() to not include the ACL or the data when in binary-upgrade mode. Adjustments made to the privileges regression test to allow another test (large_object.sql) to be added which explicitly leaves a large object with a comment in place to provide coverage of that case with pg_upgrade. Back-patch to all supported branches. Discussion: https://postgr.es/m/20170221162655.GE9812@tamriel.snowman.net
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/pg_dump/pg_backup.h1
-rw-r--r--src/bin/pg_dump/pg_backup_archiver.c12
-rw-r--r--src/bin/pg_dump/pg_dump.c34
3 files changed, 41 insertions, 6 deletions
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
index a89a8bde5da..5c974b762f3 100644
--- a/src/bin/pg_dump/pg_backup.h
+++ b/src/bin/pg_dump/pg_backup.h
@@ -149,6 +149,7 @@ typedef struct _restoreOptions
bool single_txn;
bool *idWanted; /* array showing which dump IDs to emit */
+ int binary_upgrade;
} RestoreOptions;
typedef void (*SetupWorkerPtr) (Archive *AH, RestoreOptions *ropt);
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index f156325d03e..0bae989c4c1 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -2557,7 +2557,17 @@ _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
/* Mask it if we only want schema */
if (ropt->schemaOnly)
- res = res & REQ_SCHEMA;
+ {
+ /*
+ * In binary-upgrade mode, even with schema-only set, we do not mask
+ * out large objects. Only large object definitions, comments and
+ * other information should be generated in binary-upgrade mode (not
+ * the actual data).
+ */
+ if (!(ropt->binary_upgrade && strcmp(te->desc,"BLOB") == 0) &&
+ !(ropt->binary_upgrade && strncmp(te->tag,"LARGE OBJECT ", 13) == 0))
+ res = res & REQ_SCHEMA;
+ }
/* Mask it if we only want data */
if (ropt->dataOnly)
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index bc55ba79780..a9ea3700090 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -771,7 +771,15 @@ main(int argc, char **argv)
getTableDataFKConstraints();
}
- if (outputBlobs)
+ /*
+ * In binary-upgrade mode, we do not have to worry about the actual blob
+ * data or the associated metadata that resides in the pg_largeobject and
+ * pg_largeobject_metadata tables, respectivly.
+ *
+ * However, we do need to collect blob information as there may be
+ * comments or other information on blobs that we do need to dump out.
+ */
+ if (outputBlobs || binary_upgrade)
getBlobs(fout);
/*
@@ -844,6 +852,7 @@ main(int argc, char **argv)
ropt->noTablespace = outputNoTablespaces;
ropt->disable_triggers = disable_triggers;
ropt->use_setsessauth = use_setsessauth;
+ ropt->binary_upgrade = binary_upgrade;
if (compressLevel == -1)
ropt->compression = 0;
@@ -2771,8 +2780,14 @@ dumpBlob(Archive *fout, BlobInfo *binfo)
NULL, binfo->rolname,
binfo->dobj.catId, 0, binfo->dobj.dumpId);
- /* Dump ACL if any */
- if (binfo->blobacl)
+ /*
+ * Dump ACL if any
+ *
+ * Do not dump the ACL in binary-upgrade mode, however, as the ACL will be
+ * copied over by pg_upgrade as it is part of the pg_largeobject_metadata
+ * table.
+ */
+ if (binfo->blobacl && !binary_upgrade)
dumpACL(fout, binfo->dobj.catId, binfo->dobj.dumpId, "LARGE OBJECT",
binfo->dobj.name, NULL, cquery->data,
NULL, binfo->rolname, binfo->blobacl);
@@ -2797,6 +2812,13 @@ dumpBlobs(Archive *fout, void *arg)
int i;
int cnt;
+ /*
+ * Do not dump out blob data in binary-upgrade mode, pg_upgrade will copy
+ * the pg_largeobject table over entirely from the old cluster.
+ */
+ if (binary_upgrade)
+ return 1;
+
if (g_verbose)
write_msg(NULL, "saving large objects\n");
@@ -7514,7 +7536,8 @@ dumpComment(Archive *fout, const char *target,
}
else
{
- if (schemaOnly)
+ /* We do dump blob comments in binary-upgrade mode */
+ if (schemaOnly && !binary_upgrade)
return;
}
@@ -12504,7 +12527,8 @@ dumpSecLabel(Archive *fout, const char *target,
}
else
{
- if (schemaOnly)
+ /* We do dump blob security labels in binary-upgrade mode */
+ if (schemaOnly && !binary_upgrade)
return;
}