All, * Stephen Frost ([email protected]) wrote: > Just wanted to get a note out to -hackers about the issue, I'll see > about getting a fix written up for it soon.
Attached is a patch which addresses this issue. I'm not terribly pleased with it, but I also haven't got any great ideas of what else to do. Suggestions welcome, of course. Otherwise, I'll plan to start working on the back-branch changes for this soon. Thanks! Stephen
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
new file mode 100644
index 6480fb8..983a999
*** a/src/bin/pg_dump/pg_backup.h
--- b/src/bin/pg_dump/pg_backup.h
*************** typedef struct _restoreOptions
*** 120,125 ****
--- 120,126 ----
int enable_row_security;
int sequence_data; /* dump sequence data even in schema-only mode */
int include_subscriptions;
+ int binary_upgrade;
} RestoreOptions;
typedef struct _dumpOptions
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
new file mode 100644
index 929f1b5..6c340f9
*** a/src/bin/pg_dump/pg_backup_archiver.c
--- b/src/bin/pg_dump/pg_backup_archiver.c
*************** _tocEntryRequired(TocEntry *te, teSectio
*** 2876,2882 ****
/* Mask it if we only want schema */
if (ropt->schemaOnly)
{
! if (!(ropt->sequence_data && strcmp(te->desc, "SEQUENCE SET") == 0))
res = res & REQ_SCHEMA;
}
--- 2876,2884 ----
/* Mask it if we only want schema */
if (ropt->schemaOnly)
{
! if (!(ropt->sequence_data && strcmp(te->desc, "SEQUENCE SET") == 0) &&
! !(ropt->binary_upgrade && strcmp(te->desc,"BLOB") == 0) &&
! !(ropt->binary_upgrade && strncmp(te->tag,"LARGE OBJECT ", 13) == 0))
res = res & REQ_SCHEMA;
}
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
new file mode 100644
index 89db310..44d4f32
*** a/src/bin/pg_dump/pg_dump.c
--- b/src/bin/pg_dump/pg_dump.c
*************** main(int argc, char **argv)
*** 775,781 ****
if (dopt.schemaOnly && dopt.sequence_data)
getTableData(&dopt, tblinfo, numTables, dopt.oids, RELKIND_SEQUENCE);
! if (dopt.outputBlobs)
getBlobs(fout);
/*
--- 775,789 ----
if (dopt.schemaOnly && dopt.sequence_data)
getTableData(&dopt, tblinfo, numTables, dopt.oids, RELKIND_SEQUENCE);
! /*
! * 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 security labels on blobs and we need to dump those out.
! */
! if (dopt.outputBlobs || dopt.binary_upgrade)
getBlobs(fout);
/*
*************** main(int argc, char **argv)
*** 855,860 ****
--- 863,869 ----
ropt->enable_row_security = dopt.enable_row_security;
ropt->sequence_data = dopt.sequence_data;
ropt->include_subscriptions = dopt.include_subscriptions;
+ ropt->binary_upgrade = dopt.binary_upgrade;
if (compressLevel == -1)
ropt->compression = 0;
*************** getBlobs(Archive *fout)
*** 2903,2908 ****
--- 2912,2931 ----
PQgetisnull(res, i, i_initlomacl) &&
PQgetisnull(res, i, i_initrlomacl))
binfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL;
+
+ /*
+ * In binary-upgrade mode for blobs, we do *not* dump out the data or
+ * the ACLs, should any exist. The data and ACL (if any) will be
+ * copied by pg_upgrade, which simply copies the pg_largeobject and
+ * pg_largeobject_metadata tables.
+ *
+ * We *do* dump out the definition of the blob because we need that
+ * to make the restoration of the comments, and anything else, work
+ * since pg_upgrade copies the files behind pg_largeobject and
+ * pg_largeobject_metadata after the dump is restored.
+ */
+ if (dopt->binary_upgrade)
+ binfo[i].dobj.dump &= ~(DUMP_COMPONENT_DATA | DUMP_COMPONENT_ACL);
}
/*
*************** dumpComment(Archive *fout, const char *t
*** 8831,8837 ****
}
else
{
! if (dopt->schemaOnly)
return;
}
--- 8854,8861 ----
}
else
{
! /* We do dump blob comments in binary-upgrade mode */
! if (dopt->schemaOnly && !dopt->binary_upgrade)
return;
}
*************** dumpSecLabel(Archive *fout, const char *
*** 14226,14232 ****
}
else
{
! if (dopt->schemaOnly)
return;
}
--- 14250,14257 ----
}
else
{
! /* We do dump blob security labels in binary-upgrade mode */
! if (dopt->schemaOnly && !dopt->binary_upgrade)
return;
}
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
new file mode 100644
index f73bf89..c51088a
*** a/src/bin/pg_dump/t/002_pg_dump.pl
--- b/src/bin/pg_dump/t/002_pg_dump.pl
*************** my %pgdump_runs = (
*** 39,49 ****
binary_upgrade => {
dump_cmd => [
'pg_dump',
! "--file=$tempdir/binary_upgrade.sql",
'--schema-only',
'--binary-upgrade',
'-d', 'postgres', # alternative way to specify database
! ], },
clean => {
dump_cmd => [
'pg_dump',
--- 39,55 ----
binary_upgrade => {
dump_cmd => [
'pg_dump',
! '--format=custom',
! "--file=$tempdir/binary_upgrade.dump",
'--schema-only',
'--binary-upgrade',
'-d', 'postgres', # alternative way to specify database
! ],
! restore_cmd => [
! 'pg_restore', '-Fc',
! '--verbose',
! "--file=$tempdir/binary_upgrade.sql",
! "$tempdir/binary_upgrade.dump", ], },
clean => {
dump_cmd => [
'pg_dump',
*************** my %tests = (
*** 334,339 ****
--- 340,346 ----
all_runs => 1,
regexp => qr/^ALTER LARGE OBJECT \d+ OWNER TO .*;/m,
like => {
+ binary_upgrade => 1,
clean => 1,
clean_if_exists => 1,
column_inserts => 1,
*************** my %tests = (
*** 348,354 ****
section_pre_data => 1,
test_schema_plus_blobs => 1, },
unlike => {
- binary_upgrade => 1,
no_blobs => 1,
no_owner => 1,
only_dump_test_schema => 1,
--- 355,360 ----
*************** my %tests = (
*** 666,671 ****
--- 672,678 ----
'SELECT pg_catalog.lo_from_bytea(0, \'\\x310a320a330a340a350a360a370a380a390a\');',
regexp => qr/^SELECT pg_catalog\.lo_create\('\d+'\);/m,
like => {
+ binary_upgrade => 1,
clean => 1,
clean_if_exists => 1,
column_inserts => 1,
*************** my %tests = (
*** 681,687 ****
section_pre_data => 1,
test_schema_plus_blobs => 1, },
unlike => {
- binary_upgrade => 1,
no_blobs => 1,
only_dump_test_schema => 1,
only_dump_test_table => 1,
--- 688,693 ----
diff --git a/src/test/regress/expected/large_object.out b/src/test/regress/expected/large_object.out
new file mode 100644
index ...b00d47c
*** a/src/test/regress/expected/large_object.out
--- b/src/test/regress/expected/large_object.out
***************
*** 0 ****
--- 1,15 ----
+ -- This is more-or-less DROP IF EXISTS LARGE OBJECT 3001;
+ WITH unlink AS (SELECT lo_unlink(loid) FROM pg_largeobject WHERE loid = 3001) SELECT 1;
+ ?column?
+ ----------
+ 1
+ (1 row)
+
+ -- Test creation of a large object and leave it for testing pg_upgrade
+ SELECT lo_create(3001);
+ lo_create
+ -----------
+ 3001
+ (1 row)
+
+ COMMENT ON LARGE OBJECT 3001 IS 'testing comments';
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
new file mode 100644
index f66b443..1af66ff
*** a/src/test/regress/expected/privileges.out
--- b/src/test/regress/expected/privileges.out
*************** DROP ROLE IF EXISTS regress_user3;
*** 12,18 ****
DROP ROLE IF EXISTS regress_user4;
DROP ROLE IF EXISTS regress_user5;
DROP ROLE IF EXISTS regress_user6;
! SELECT lo_unlink(oid) FROM pg_largeobject_metadata;
lo_unlink
-----------
(0 rows)
--- 12,18 ----
DROP ROLE IF EXISTS regress_user4;
DROP ROLE IF EXISTS regress_user5;
DROP ROLE IF EXISTS regress_user6;
! SELECT lo_unlink(oid) FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000;
lo_unlink
-----------
(0 rows)
*************** SELECT lo_unlink(2002);
*** 1173,1183 ****
\c -
-- confirm ACL setting
! SELECT oid, pg_get_userbyid(lomowner) ownername, lomacl FROM pg_largeobject_metadata;
oid | ownername | lomacl
------+---------------+------------------------------------------------------------------------------------------------
- 1002 | regress_user1 |
1001 | regress_user1 | {regress_user1=rw/regress_user1,=rw/regress_user1}
1003 | regress_user1 | {regress_user1=rw/regress_user1,regress_user2=r/regress_user1}
1004 | regress_user1 | {regress_user1=rw/regress_user1,regress_user2=rw/regress_user1}
1005 | regress_user1 | {regress_user1=rw/regress_user1,regress_user2=r*w/regress_user1,regress_user3=r/regress_user2}
--- 1173,1183 ----
\c -
-- confirm ACL setting
! SELECT oid, pg_get_userbyid(lomowner) ownername, lomacl FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid;
oid | ownername | lomacl
------+---------------+------------------------------------------------------------------------------------------------
1001 | regress_user1 | {regress_user1=rw/regress_user1,=rw/regress_user1}
+ 1002 | regress_user1 |
1003 | regress_user1 | {regress_user1=rw/regress_user1,regress_user2=r/regress_user1}
1004 | regress_user1 | {regress_user1=rw/regress_user1,regress_user2=rw/regress_user1}
1005 | regress_user1 | {regress_user1=rw/regress_user1,regress_user2=r*w/regress_user1,regress_user3=r/regress_user2}
*************** DROP TABLE atest6;
*** 1546,1552 ****
DROP TABLE atestc;
DROP TABLE atestp1;
DROP TABLE atestp2;
! SELECT lo_unlink(oid) FROM pg_largeobject_metadata;
lo_unlink
-----------
1
--- 1546,1552 ----
DROP TABLE atestc;
DROP TABLE atestp1;
DROP TABLE atestp2;
! SELECT lo_unlink(oid) FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000;
lo_unlink
-----------
1
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
new file mode 100644
index edeb2d6..1f2fb59
*** a/src/test/regress/parallel_schedule
--- b/src/test/regress/parallel_schedule
*************** test: select_into select_distinct select
*** 84,90 ****
# ----------
# Another group of parallel tests
# ----------
! test: brin gin gist spgist privileges init_privs security_label collate matview lock replica_identity rowsecurity object_address tablesample groupingsets drop_operator
# ----------
# Another group of parallel tests
--- 84,90 ----
# ----------
# Another group of parallel tests
# ----------
! test: brin gin gist spgist privileges init_privs security_label collate matview lock replica_identity rowsecurity object_address tablesample groupingsets drop_operator large_object
# ----------
# Another group of parallel tests
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
new file mode 100644
index 27a46d7..9ffceff
*** a/src/test/regress/serial_schedule
--- b/src/test/regress/serial_schedule
*************** test: object_address
*** 116,121 ****
--- 116,122 ----
test: tablesample
test: groupingsets
test: drop_operator
+ test: large_object
test: alter_generic
test: alter_operator
test: misc
diff --git a/src/test/regress/sql/large_object.sql b/src/test/regress/sql/large_object.sql
new file mode 100644
index ...a9e18b7
*** a/src/test/regress/sql/large_object.sql
--- b/src/test/regress/sql/large_object.sql
***************
*** 0 ****
--- 1,8 ----
+
+ -- This is more-or-less DROP IF EXISTS LARGE OBJECT 3001;
+ WITH unlink AS (SELECT lo_unlink(loid) FROM pg_largeobject WHERE loid = 3001) SELECT 1;
+
+ -- Test creation of a large object and leave it for testing pg_upgrade
+ SELECT lo_create(3001);
+
+ COMMENT ON LARGE OBJECT 3001 IS 'testing comments';
diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql
new file mode 100644
index 00dc7bd..82d6751
*** a/src/test/regress/sql/privileges.sql
--- b/src/test/regress/sql/privileges.sql
*************** DROP ROLE IF EXISTS regress_user4;
*** 17,23 ****
DROP ROLE IF EXISTS regress_user5;
DROP ROLE IF EXISTS regress_user6;
! SELECT lo_unlink(oid) FROM pg_largeobject_metadata;
RESET client_min_messages;
--- 17,23 ----
DROP ROLE IF EXISTS regress_user5;
DROP ROLE IF EXISTS regress_user6;
! SELECT lo_unlink(oid) FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000;
RESET client_min_messages;
*************** SELECT lo_unlink(2002);
*** 729,735 ****
\c -
-- confirm ACL setting
! SELECT oid, pg_get_userbyid(lomowner) ownername, lomacl FROM pg_largeobject_metadata;
SET SESSION AUTHORIZATION regress_user3;
--- 729,735 ----
\c -
-- confirm ACL setting
! SELECT oid, pg_get_userbyid(lomowner) ownername, lomacl FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid;
SET SESSION AUTHORIZATION regress_user3;
*************** DROP TABLE atestc;
*** 960,966 ****
DROP TABLE atestp1;
DROP TABLE atestp2;
! SELECT lo_unlink(oid) FROM pg_largeobject_metadata;
DROP GROUP regress_group1;
DROP GROUP regress_group2;
--- 960,966 ----
DROP TABLE atestp1;
DROP TABLE atestp2;
! SELECT lo_unlink(oid) FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000;
DROP GROUP regress_group1;
DROP GROUP regress_group2;
signature.asc
Description: Digital signature
