|
49 | 49 | #include "catalog/pg_class_d.h"
|
50 | 50 | #include "catalog/pg_default_acl_d.h"
|
51 | 51 | #include "catalog/pg_largeobject_d.h"
|
| 52 | +#include "catalog/pg_largeobject_metadata_d.h" |
52 | 53 | #include "catalog/pg_proc_d.h"
|
53 | 54 | #include "catalog/pg_publication_d.h"
|
| 55 | +#include "catalog/pg_shdepend_d.h" |
54 | 56 | #include "catalog/pg_subscription_d.h"
|
55 | 57 | #include "catalog/pg_type_d.h"
|
56 | 58 | #include "common/connect.h"
|
@@ -209,6 +211,12 @@ static int nbinaryUpgradeClassOids = 0;
|
209 | 211 | static SequenceItem *sequences = NULL;
|
210 | 212 | static int nsequences = 0;
|
211 | 213 |
|
| 214 | +/* |
| 215 | + * For binary upgrade, the dump ID of pg_largeobject_metadata is saved for use |
| 216 | + * as a dependency for pg_shdepend and any large object comments/seclabels. |
| 217 | + */ |
| 218 | +static DumpId lo_metadata_dumpId; |
| 219 | + |
212 | 220 | /* Maximum number of relations to fetch in a fetchAttributeStats() call. */
|
213 | 221 | #define MAX_ATTR_STATS_RELS 64
|
214 | 222 |
|
@@ -1085,6 +1093,36 @@ main(int argc, char **argv)
|
1085 | 1093 | if (!dopt.dumpData && dopt.sequence_data)
|
1086 | 1094 | getTableData(&dopt, tblinfo, numTables, RELKIND_SEQUENCE);
|
1087 | 1095 |
|
| 1096 | + /* |
| 1097 | + * For binary upgrade mode, dump pg_largeobject_metadata and the |
| 1098 | + * associated pg_shdepend rows. This is faster to restore than the |
| 1099 | + * equivalent set of large object commands. We can only do this for |
| 1100 | + * upgrades from v12 and newer; in older versions, pg_largeobject_metadata |
| 1101 | + * was created WITH OIDS, so the OID column is hidden and won't be dumped. |
| 1102 | + */ |
| 1103 | + if (dopt.binary_upgrade && fout->remoteVersion >= 120000) |
| 1104 | + { |
| 1105 | + TableInfo *lo_metadata = findTableByOid(LargeObjectMetadataRelationId); |
| 1106 | + TableInfo *shdepend = findTableByOid(SharedDependRelationId); |
| 1107 | + |
| 1108 | + makeTableDataInfo(&dopt, lo_metadata); |
| 1109 | + makeTableDataInfo(&dopt, shdepend); |
| 1110 | + |
| 1111 | + /* |
| 1112 | + * Save pg_largeobject_metadata's dump ID for use as a dependency for |
| 1113 | + * pg_shdepend and any large object comments/seclabels. |
| 1114 | + */ |
| 1115 | + lo_metadata_dumpId = lo_metadata->dataObj->dobj.dumpId; |
| 1116 | + addObjectDependency(&shdepend->dataObj->dobj, lo_metadata_dumpId); |
| 1117 | + |
| 1118 | + /* |
| 1119 | + * Only dump large object shdepend rows for this database. |
| 1120 | + */ |
| 1121 | + shdepend->dataObj->filtercond = "WHERE classid = 'pg_largeobject'::regclass " |
| 1122 | + "AND dbid = (SELECT oid FROM pg_database " |
| 1123 | + " WHERE datname = current_database())"; |
| 1124 | + } |
| 1125 | + |
1088 | 1126 | /*
|
1089 | 1127 | * In binary-upgrade mode, we do not have to worry about the actual LO
|
1090 | 1128 | * data or the associated metadata that resides in the pg_largeobject and
|
@@ -3924,10 +3962,37 @@ getLOs(Archive *fout)
|
3924 | 3962 | * as it will be copied by pg_upgrade, which simply copies the
|
3925 | 3963 | * pg_largeobject table. We *do* however dump out anything but the
|
3926 | 3964 | * data, as pg_upgrade copies just pg_largeobject, but not
|
3927 |
| - * pg_largeobject_metadata, after the dump is restored. |
| 3965 | + * pg_largeobject_metadata, after the dump is restored. In versions |
| 3966 | + * before v12, this is done via proper large object commands. In |
| 3967 | + * newer versions, we dump the content of pg_largeobject_metadata and |
| 3968 | + * any associated pg_shdepend rows, which is faster to restore. (On |
| 3969 | + * <v12, pg_largeobject_metadata was created WITH OIDS, so the OID |
| 3970 | + * column is hidden and won't be dumped.) |
3928 | 3971 | */
|
3929 | 3972 | if (dopt->binary_upgrade)
|
3930 |
| - loinfo->dobj.dump &= ~DUMP_COMPONENT_DATA; |
| 3973 | + { |
| 3974 | + if (fout->remoteVersion >= 120000) |
| 3975 | + { |
| 3976 | + /* |
| 3977 | + * We should've saved pg_largeobject_metadata's dump ID before |
| 3978 | + * this point. |
| 3979 | + */ |
| 3980 | + Assert(lo_metadata_dumpId); |
| 3981 | + |
| 3982 | + loinfo->dobj.dump &= ~(DUMP_COMPONENT_DATA | DUMP_COMPONENT_ACL | DUMP_COMPONENT_DEFINITION); |
| 3983 | + |
| 3984 | + /* |
| 3985 | + * Mark the large object as dependent on |
| 3986 | + * pg_largeobject_metadata so that any large object |
| 3987 | + * comments/seclables are dumped after it. |
| 3988 | + */ |
| 3989 | + loinfo->dobj.dependencies = (DumpId *) pg_malloc(sizeof(DumpId)); |
| 3990 | + loinfo->dobj.dependencies[0] = lo_metadata_dumpId; |
| 3991 | + loinfo->dobj.nDeps = loinfo->dobj.allocDeps = 1; |
| 3992 | + } |
| 3993 | + else |
| 3994 | + loinfo->dobj.dump &= ~DUMP_COMPONENT_DATA; |
| 3995 | + } |
3931 | 3996 |
|
3932 | 3997 | /*
|
3933 | 3998 | * Create a "BLOBS" data item for the group, too. This is just a
|
@@ -9039,8 +9104,20 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
|
9039 | 9104 | if (tbinfo->relkind == RELKIND_SEQUENCE)
|
9040 | 9105 | continue;
|
9041 | 9106 |
|
9042 |
| - /* Don't bother with uninteresting tables, either */ |
9043 |
| - if (!tbinfo->interesting) |
| 9107 | + /* |
| 9108 | + * Don't bother with uninteresting tables, either. For binary |
| 9109 | + * upgrades, this is bypassed for pg_largeobject_metadata and |
| 9110 | + * pg_shdepend so that the columns names are collected for the |
| 9111 | + * corresponding COPY commands. Restoring the data for those catalogs |
| 9112 | + * is faster than restoring the equivalent set of large object |
| 9113 | + * commands. We can only do this for upgrades from v12 and newer; in |
| 9114 | + * older versions, pg_largeobject_metadata was created WITH OIDS, so |
| 9115 | + * the OID column is hidden and won't be dumped. |
| 9116 | + */ |
| 9117 | + if (!tbinfo->interesting && |
| 9118 | + !(fout->dopt->binary_upgrade && fout->remoteVersion >= 120000 && |
| 9119 | + (tbinfo->dobj.catId.oid == LargeObjectMetadataRelationId || |
| 9120 | + tbinfo->dobj.catId.oid == SharedDependRelationId))) |
9044 | 9121 | continue;
|
9045 | 9122 |
|
9046 | 9123 | /* OK, we need info for this table */
|
@@ -9244,7 +9321,10 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
|
9244 | 9321 | pg_fatal("unrecognized table OID %u", attrelid);
|
9245 | 9322 | /* cross-check that we only got requested tables */
|
9246 | 9323 | if (tbinfo->relkind == RELKIND_SEQUENCE ||
|
9247 |
| - !tbinfo->interesting) |
| 9324 | + (!tbinfo->interesting && |
| 9325 | + !(fout->dopt->binary_upgrade && fout->remoteVersion >= 120000 && |
| 9326 | + (tbinfo->dobj.catId.oid == LargeObjectMetadataRelationId || |
| 9327 | + tbinfo->dobj.catId.oid == SharedDependRelationId)))) |
9248 | 9328 | pg_fatal("unexpected column data for table \"%s\"",
|
9249 | 9329 | tbinfo->dobj.name);
|
9250 | 9330 |
|
|
0 commit comments