Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 65a3f23

Browse files
committed
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
1 parent 943140d commit 65a3f23

File tree

9 files changed

+72
-12
lines changed

9 files changed

+72
-12
lines changed

src/bin/pg_dump/pg_backup.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ typedef struct _restoreOptions
117117

118118
bool *idWanted; /* array showing which dump IDs to emit */
119119
int enable_row_security;
120+
int binary_upgrade;
120121
} RestoreOptions;
121122

122123
typedef struct _dumpOptions

src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2842,7 +2842,17 @@ _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
28422842

28432843
/* Mask it if we only want schema */
28442844
if (ropt->schemaOnly)
2845-
res = res & REQ_SCHEMA;
2845+
{
2846+
/*
2847+
* In binary-upgrade mode, even with schema-only set, we do not mask
2848+
* out large objects. Only large object definitions, comments and
2849+
* other information should be generated in binary-upgrade mode (not
2850+
* the actual data).
2851+
*/
2852+
if (!(ropt->binary_upgrade && strcmp(te->desc,"BLOB") == 0) &&
2853+
!(ropt->binary_upgrade && strncmp(te->tag,"LARGE OBJECT ", 13) == 0))
2854+
res = res & REQ_SCHEMA;
2855+
}
28462856

28472857
/* Mask it if we only want data */
28482858
if (ropt->dataOnly)

src/bin/pg_dump/pg_dump.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,15 @@ main(int argc, char **argv)
762762
getTableDataFKConstraints();
763763
}
764764

765-
if (dopt.outputBlobs)
765+
/*
766+
* In binary-upgrade mode, we do not have to worry about the actual blob
767+
* data or the associated metadata that resides in the pg_largeobject and
768+
* pg_largeobject_metadata tables, respectivly.
769+
*
770+
* However, we do need to collect blob information as there may be
771+
* comments or other information on blobs that we do need to dump out.
772+
*/
773+
if (dopt.outputBlobs || dopt.binary_upgrade)
766774
getBlobs(fout);
767775

768776
/*
@@ -845,6 +853,7 @@ main(int argc, char **argv)
845853
ropt->lockWaitTimeout = dopt.lockWaitTimeout;
846854
ropt->include_everything = dopt.include_everything;
847855
ropt->enable_row_security = dopt.enable_row_security;
856+
ropt->binary_upgrade = dopt.binary_upgrade;
848857

849858
if (compressLevel == -1)
850859
ropt->compression = 0;
@@ -2938,6 +2947,20 @@ getBlobs(Archive *fout)
29382947
PQgetisnull(res, i, i_initlomacl) &&
29392948
PQgetisnull(res, i, i_initrlomacl))
29402949
binfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL;
2950+
2951+
/*
2952+
* In binary-upgrade mode for blobs, we do *not* dump out the data or
2953+
* the ACLs, should any exist. The data and ACL (if any) will be
2954+
* copied by pg_upgrade, which simply copies the pg_largeobject and
2955+
* pg_largeobject_metadata tables.
2956+
*
2957+
* We *do* dump out the definition of the blob because we need that to
2958+
* make the restoration of the comments, and anything else, work since
2959+
* pg_upgrade copies the files behind pg_largeobject and
2960+
* pg_largeobject_metadata after the dump is restored.
2961+
*/
2962+
if (dopt->binary_upgrade)
2963+
binfo[i].dobj.dump &= ~(DUMP_COMPONENT_DATA | DUMP_COMPONENT_ACL);
29412964
}
29422965

29432966
/*
@@ -9103,7 +9126,8 @@ dumpComment(Archive *fout, const char *target,
91039126
}
91049127
else
91059128
{
9106-
if (dopt->schemaOnly)
9129+
/* We do dump blob comments in binary-upgrade mode */
9130+
if (dopt->schemaOnly && !dopt->binary_upgrade)
91079131
return;
91089132
}
91099133

@@ -14803,7 +14827,8 @@ dumpSecLabel(Archive *fout, const char *target,
1480314827
}
1480414828
else
1480514829
{
14806-
if (dopt->schemaOnly)
14830+
/* We do dump blob security labels in binary-upgrade mode */
14831+
if (dopt->schemaOnly && !dopt->binary_upgrade)
1480714832
return;
1480814833
}
1480914834

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
-- This is more-or-less DROP IF EXISTS LARGE OBJECT 3001;
2+
WITH unlink AS (SELECT lo_unlink(loid) FROM pg_largeobject WHERE loid = 3001) SELECT 1;
3+
?column?
4+
----------
5+
1
6+
(1 row)
7+
8+
-- Test creation of a large object and leave it for testing pg_upgrade
9+
SELECT lo_create(3001);
10+
lo_create
11+
-----------
12+
3001
13+
(1 row)
14+
15+
COMMENT ON LARGE OBJECT 3001 IS 'testing comments';

src/test/regress/expected/privileges.out

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ DROP ROLE IF EXISTS regress_user3;
1212
DROP ROLE IF EXISTS regress_user4;
1313
DROP ROLE IF EXISTS regress_user5;
1414
DROP ROLE IF EXISTS regress_user6;
15-
SELECT lo_unlink(oid) FROM pg_largeobject_metadata;
15+
SELECT lo_unlink(oid) FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid;
1616
lo_unlink
1717
-----------
1818
(0 rows)
@@ -1173,11 +1173,11 @@ SELECT lo_unlink(2002);
11731173

11741174
\c -
11751175
-- confirm ACL setting
1176-
SELECT oid, pg_get_userbyid(lomowner) ownername, lomacl FROM pg_largeobject_metadata;
1176+
SELECT oid, pg_get_userbyid(lomowner) ownername, lomacl FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid;
11771177
oid | ownername | lomacl
11781178
------+---------------+------------------------------------------------------------------------------------------------
1179-
1002 | regress_user1 |
11801179
1001 | regress_user1 | {regress_user1=rw/regress_user1,=rw/regress_user1}
1180+
1002 | regress_user1 |
11811181
1003 | regress_user1 | {regress_user1=rw/regress_user1,regress_user2=r/regress_user1}
11821182
1004 | regress_user1 | {regress_user1=rw/regress_user1,regress_user2=rw/regress_user1}
11831183
1005 | regress_user1 | {regress_user1=rw/regress_user1,regress_user2=r*w/regress_user1,regress_user3=r/regress_user2}
@@ -1546,7 +1546,7 @@ DROP TABLE atest6;
15461546
DROP TABLE atestc;
15471547
DROP TABLE atestp1;
15481548
DROP TABLE atestp2;
1549-
SELECT lo_unlink(oid) FROM pg_largeobject_metadata;
1549+
SELECT lo_unlink(oid) FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid;
15501550
lo_unlink
15511551
-----------
15521552
1

src/test/regress/parallel_schedule

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ test: select_into select_distinct select_distinct_on select_implicit select_havi
8484
# ----------
8585
# Another group of parallel tests
8686
# ----------
87-
test: brin gin gist spgist privileges init_privs security_label collate matview lock replica_identity rowsecurity object_address tablesample groupingsets drop_operator
87+
test: brin gin gist spgist privileges init_privs security_label collate matview lock replica_identity rowsecurity object_address tablesample groupingsets drop_operator large_object
8888

8989
# ----------
9090
# Another group of parallel tests

src/test/regress/serial_schedule

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ test: object_address
116116
test: tablesample
117117
test: groupingsets
118118
test: drop_operator
119+
test: large_object
119120
test: alter_generic
120121
test: alter_operator
121122
test: misc

src/test/regress/sql/large_object.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
-- This is more-or-less DROP IF EXISTS LARGE OBJECT 3001;
3+
WITH unlink AS (SELECT lo_unlink(loid) FROM pg_largeobject WHERE loid = 3001) SELECT 1;
4+
5+
-- Test creation of a large object and leave it for testing pg_upgrade
6+
SELECT lo_create(3001);
7+
8+
COMMENT ON LARGE OBJECT 3001 IS 'testing comments';

src/test/regress/sql/privileges.sql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ DROP ROLE IF EXISTS regress_user4;
1717
DROP ROLE IF EXISTS regress_user5;
1818
DROP ROLE IF EXISTS regress_user6;
1919

20-
SELECT lo_unlink(oid) FROM pg_largeobject_metadata;
20+
SELECT lo_unlink(oid) FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid;
2121

2222
RESET client_min_messages;
2323

@@ -729,7 +729,7 @@ SELECT lo_unlink(2002);
729729

730730
\c -
731731
-- confirm ACL setting
732-
SELECT oid, pg_get_userbyid(lomowner) ownername, lomacl FROM pg_largeobject_metadata;
732+
SELECT oid, pg_get_userbyid(lomowner) ownername, lomacl FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid;
733733

734734
SET SESSION AUTHORIZATION regress_user3;
735735

@@ -960,7 +960,7 @@ DROP TABLE atestc;
960960
DROP TABLE atestp1;
961961
DROP TABLE atestp2;
962962

963-
SELECT lo_unlink(oid) FROM pg_largeobject_metadata;
963+
SELECT lo_unlink(oid) FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid;
964964

965965
DROP GROUP regress_group1;
966966
DROP GROUP regress_group2;

0 commit comments

Comments
 (0)