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

Commit 9a974cb

Browse files
committed
pg_upgrade: Preserve relfilenodes and tablespace OIDs.
Currently, database OIDs, relfilenodes, and tablespace OIDs can all change when a cluster is upgraded using pg_upgrade. It seems better to preserve them, because (1) it makes troubleshooting pg_upgrade easier, since you don't have to do a lot of work to match up files in the old and new clusters, (2) it allows 'rsync' to save bandwidth when used to re-sync a cluster after an upgrade, and (3) if we ever encrypt or sign blocks, we would likely want to use a nonce that depends on these values. This patch only arranges to preserve relfilenodes and tablespace OIDs. The task of preserving database OIDs is left for another patch, since it involves some complexities that don't exist in these cases. Database OIDs have a similar issue, but there are some tricky points in that case that do not apply to these cases, so that problem is left for another patch. Shruthi KC, based on an earlier patch from Antonin Houska, reviewed and with some adjustments by me. Discussion: http://postgr.es/m/CA+TgmoYgTwYcUmB=e8+hRHOFA0kkS6Kde85+UNdon6q7bt1niQ@mail.gmail.com
1 parent 2131c04 commit 9a974cb

File tree

16 files changed

+247
-108
lines changed

16 files changed

+247
-108
lines changed

src/backend/bootstrap/bootparse.y

+2-1
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ Boot_CreateStmt:
212212
mapped_relation,
213213
true,
214214
&relfrozenxid,
215-
&relminmxid);
215+
&relminmxid,
216+
true);
216217
elog(DEBUG4, "bootstrap relation created");
217218
}
218219
else

src/backend/catalog/heap.c

+48-15
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@
9191

9292
/* Potentially set by pg_upgrade_support functions */
9393
Oid binary_upgrade_next_heap_pg_class_oid = InvalidOid;
94+
Oid binary_upgrade_next_heap_pg_class_relfilenode = InvalidOid;
9495
Oid binary_upgrade_next_toast_pg_class_oid = InvalidOid;
96+
Oid binary_upgrade_next_toast_pg_class_relfilenode = InvalidOid;
9597

9698
static void AddNewRelationTuple(Relation pg_class_desc,
9799
Relation new_rel_desc,
@@ -285,8 +287,12 @@ SystemAttributeByName(const char *attname)
285287
* heap_create - Create an uncataloged heap relation
286288
*
287289
* Note API change: the caller must now always provide the OID
288-
* to use for the relation. The relfilenode may (and, normally,
289-
* should) be left unspecified.
290+
* to use for the relation. The relfilenode may be (and in
291+
* the simplest cases is) left unspecified.
292+
*
293+
* create_storage indicates whether or not to create the storage.
294+
* However, even if create_storage is true, no storage will be
295+
* created if the relkind is one that doesn't have storage.
290296
*
291297
* rel->rd_rel is initialized by RelationBuildLocalRelation,
292298
* and is mostly zeroes at return.
@@ -306,9 +312,9 @@ heap_create(const char *relname,
306312
bool mapped_relation,
307313
bool allow_system_table_mods,
308314
TransactionId *relfrozenxid,
309-
MultiXactId *relminmxid)
315+
MultiXactId *relminmxid,
316+
bool create_storage)
310317
{
311-
bool create_storage;
312318
Relation rel;
313319

314320
/* The caller must have provided an OID for the relation. */
@@ -343,17 +349,17 @@ heap_create(const char *relname,
343349
if (!RELKIND_HAS_TABLESPACE(relkind))
344350
reltablespace = InvalidOid;
345351

346-
/*
347-
* Decide whether to create storage. If caller passed a valid relfilenode,
348-
* storage is already created, so don't do it here. Also don't create it
349-
* for relkinds without physical storage.
350-
*/
351-
if (!RELKIND_HAS_STORAGE(relkind) || OidIsValid(relfilenode))
352+
/* Don't create storage for relkinds without physical storage. */
353+
if (!RELKIND_HAS_STORAGE(relkind))
352354
create_storage = false;
353355
else
354356
{
355-
create_storage = true;
356-
relfilenode = relid;
357+
/*
358+
* If relfilenode is unspecified by the caller then create storage
359+
* with oid same as relid.
360+
*/
361+
if (!OidIsValid(relfilenode))
362+
relfilenode = relid;
357363
}
358364

359365
/*
@@ -1121,6 +1127,9 @@ heap_create_with_catalog(const char *relname,
11211127
Oid existing_relid;
11221128
Oid old_type_oid;
11231129
Oid new_type_oid;
1130+
1131+
/* By default set to InvalidOid unless overridden by binary-upgrade */
1132+
Oid relfilenode = InvalidOid;
11241133
TransactionId relfrozenxid;
11251134
MultiXactId relminmxid;
11261135

@@ -1183,7 +1192,7 @@ heap_create_with_catalog(const char *relname,
11831192
*/
11841193
if (!OidIsValid(relid))
11851194
{
1186-
/* Use binary-upgrade override for pg_class.oid/relfilenode? */
1195+
/* Use binary-upgrade override for pg_class.oid and relfilenode */
11871196
if (IsBinaryUpgrade)
11881197
{
11891198
/*
@@ -1200,6 +1209,14 @@ heap_create_with_catalog(const char *relname,
12001209
{
12011210
relid = binary_upgrade_next_toast_pg_class_oid;
12021211
binary_upgrade_next_toast_pg_class_oid = InvalidOid;
1212+
1213+
if (!OidIsValid(binary_upgrade_next_toast_pg_class_relfilenode))
1214+
ereport(ERROR,
1215+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1216+
errmsg("toast relfilenode value not set when in binary upgrade mode")));
1217+
1218+
relfilenode = binary_upgrade_next_toast_pg_class_relfilenode;
1219+
binary_upgrade_next_toast_pg_class_relfilenode = InvalidOid;
12031220
}
12041221
}
12051222
else
@@ -1211,6 +1228,17 @@ heap_create_with_catalog(const char *relname,
12111228

12121229
relid = binary_upgrade_next_heap_pg_class_oid;
12131230
binary_upgrade_next_heap_pg_class_oid = InvalidOid;
1231+
1232+
if (RELKIND_HAS_STORAGE(relkind))
1233+
{
1234+
if (!OidIsValid(binary_upgrade_next_heap_pg_class_relfilenode))
1235+
ereport(ERROR,
1236+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1237+
errmsg("relfilenode value not set when in binary upgrade mode")));
1238+
1239+
relfilenode = binary_upgrade_next_heap_pg_class_relfilenode;
1240+
binary_upgrade_next_heap_pg_class_relfilenode = InvalidOid;
1241+
}
12141242
}
12151243
}
12161244

@@ -1250,12 +1278,16 @@ heap_create_with_catalog(const char *relname,
12501278
* Create the relcache entry (mostly dummy at this point) and the physical
12511279
* disk file. (If we fail further down, it's the smgr's responsibility to
12521280
* remove the disk file again.)
1281+
*
1282+
* NB: Note that passing create_storage = true is correct even for binary
1283+
* upgrade. The storage we create here will be replaced later, but we need
1284+
* to have something on disk in the meanwhile.
12531285
*/
12541286
new_rel_desc = heap_create(relname,
12551287
relnamespace,
12561288
reltablespace,
12571289
relid,
1258-
InvalidOid,
1290+
relfilenode,
12591291
accessmtd,
12601292
tupdesc,
12611293
relkind,
@@ -1264,7 +1296,8 @@ heap_create_with_catalog(const char *relname,
12641296
mapped_relation,
12651297
allow_system_table_mods,
12661298
&relfrozenxid,
1267-
&relminmxid);
1299+
&relminmxid,
1300+
true);
12681301

12691302
Assert(relid == RelationGetRelid(new_rel_desc));
12701303

src/backend/catalog/index.c

+21-2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787

8888
/* Potentially set by pg_upgrade_support functions */
8989
Oid binary_upgrade_next_index_pg_class_oid = InvalidOid;
90+
Oid binary_upgrade_next_index_pg_class_relfilenode = InvalidOid;
9091

9192
/*
9293
* Pointer-free representation of variables used when reindexing system
@@ -733,6 +734,7 @@ index_create(Relation heapRelation,
733734
char relkind;
734735
TransactionId relfrozenxid;
735736
MultiXactId relminmxid;
737+
bool create_storage = !OidIsValid(relFileNode);
736738

737739
/* constraint flags can only be set when a constraint is requested */
738740
Assert((constr_flags == 0) ||
@@ -904,7 +906,7 @@ index_create(Relation heapRelation,
904906
*/
905907
if (!OidIsValid(indexRelationId))
906908
{
907-
/* Use binary-upgrade override for pg_class.oid/relfilenode? */
909+
/* Use binary-upgrade override for pg_class.oid and relfilenode */
908910
if (IsBinaryUpgrade)
909911
{
910912
if (!OidIsValid(binary_upgrade_next_index_pg_class_oid))
@@ -914,6 +916,22 @@ index_create(Relation heapRelation,
914916

915917
indexRelationId = binary_upgrade_next_index_pg_class_oid;
916918
binary_upgrade_next_index_pg_class_oid = InvalidOid;
919+
920+
/* Overide the index relfilenode */
921+
if ((relkind == RELKIND_INDEX) &&
922+
(!OidIsValid(binary_upgrade_next_index_pg_class_relfilenode)))
923+
ereport(ERROR,
924+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
925+
errmsg("index relfilenode value not set when in binary upgrade mode")));
926+
relFileNode = binary_upgrade_next_index_pg_class_relfilenode;
927+
binary_upgrade_next_index_pg_class_relfilenode = InvalidOid;
928+
929+
/*
930+
* Note that we want create_storage = true for binary upgrade.
931+
* The storage we create here will be replaced later, but we need
932+
* to have something on disk in the meanwhile.
933+
*/
934+
Assert(create_storage);
917935
}
918936
else
919937
{
@@ -940,7 +958,8 @@ index_create(Relation heapRelation,
940958
mapped_relation,
941959
allow_system_table_mods,
942960
&relfrozenxid,
943-
&relminmxid);
961+
&relminmxid,
962+
create_storage);
944963

945964
Assert(relfrozenxid == InvalidTransactionId);
946965
Assert(relminmxid == InvalidMultiXactId);

src/backend/commands/tablespace.c

+15-2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ char *default_tablespace = NULL;
8989
char *temp_tablespaces = NULL;
9090
bool allow_in_place_tablespaces = false;
9191

92+
Oid binary_upgrade_next_pg_tablespace_oid = InvalidOid;
9293

9394
static void create_tablespace_directories(const char *location,
9495
const Oid tablespaceoid);
@@ -340,8 +341,20 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
340341

341342
MemSet(nulls, false, sizeof(nulls));
342343

343-
tablespaceoid = GetNewOidWithIndex(rel, TablespaceOidIndexId,
344-
Anum_pg_tablespace_oid);
344+
if (IsBinaryUpgrade)
345+
{
346+
/* Use binary-upgrade override for tablespace oid */
347+
if (!OidIsValid(binary_upgrade_next_pg_tablespace_oid))
348+
ereport(ERROR,
349+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
350+
errmsg("pg_tablespace OID value not set when in binary upgrade mode")));
351+
352+
tablespaceoid = binary_upgrade_next_pg_tablespace_oid;
353+
binary_upgrade_next_pg_tablespace_oid = InvalidOid;
354+
}
355+
else
356+
tablespaceoid = GetNewOidWithIndex(rel, TablespaceOidIndexId,
357+
Anum_pg_tablespace_oid);
345358
values[Anum_pg_tablespace_oid - 1] = ObjectIdGetDatum(tablespaceoid);
346359
values[Anum_pg_tablespace_spcname - 1] =
347360
DirectFunctionCall1(namein, CStringGetDatum(stmt->tablespacename));

src/backend/utils/adt/pg_upgrade_support.c

+44
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@ do { \
2929
errmsg("function can only be called when server is in binary upgrade mode"))); \
3030
} while (0)
3131

32+
Datum
33+
binary_upgrade_set_next_pg_tablespace_oid(PG_FUNCTION_ARGS)
34+
{
35+
Oid tbspoid = PG_GETARG_OID(0);
36+
37+
CHECK_IS_BINARY_UPGRADE;
38+
binary_upgrade_next_pg_tablespace_oid = tbspoid;
39+
40+
PG_RETURN_VOID();
41+
}
42+
3243
Datum
3344
binary_upgrade_set_next_pg_type_oid(PG_FUNCTION_ARGS)
3445
{
@@ -84,6 +95,17 @@ binary_upgrade_set_next_heap_pg_class_oid(PG_FUNCTION_ARGS)
8495
PG_RETURN_VOID();
8596
}
8697

98+
Datum
99+
binary_upgrade_set_next_heap_relfilenode(PG_FUNCTION_ARGS)
100+
{
101+
Oid nodeoid = PG_GETARG_OID(0);
102+
103+
CHECK_IS_BINARY_UPGRADE;
104+
binary_upgrade_next_heap_pg_class_relfilenode = nodeoid;
105+
106+
PG_RETURN_VOID();
107+
}
108+
87109
Datum
88110
binary_upgrade_set_next_index_pg_class_oid(PG_FUNCTION_ARGS)
89111
{
@@ -95,6 +117,17 @@ binary_upgrade_set_next_index_pg_class_oid(PG_FUNCTION_ARGS)
95117
PG_RETURN_VOID();
96118
}
97119

120+
Datum
121+
binary_upgrade_set_next_index_relfilenode(PG_FUNCTION_ARGS)
122+
{
123+
Oid nodeoid = PG_GETARG_OID(0);
124+
125+
CHECK_IS_BINARY_UPGRADE;
126+
binary_upgrade_next_index_pg_class_relfilenode = nodeoid;
127+
128+
PG_RETURN_VOID();
129+
}
130+
98131
Datum
99132
binary_upgrade_set_next_toast_pg_class_oid(PG_FUNCTION_ARGS)
100133
{
@@ -106,6 +139,17 @@ binary_upgrade_set_next_toast_pg_class_oid(PG_FUNCTION_ARGS)
106139
PG_RETURN_VOID();
107140
}
108141

142+
Datum
143+
binary_upgrade_set_next_toast_relfilenode(PG_FUNCTION_ARGS)
144+
{
145+
Oid nodeoid = PG_GETARG_OID(0);
146+
147+
CHECK_IS_BINARY_UPGRADE;
148+
binary_upgrade_next_toast_pg_class_relfilenode = nodeoid;
149+
150+
PG_RETURN_VOID();
151+
}
152+
109153
Datum
110154
binary_upgrade_set_next_pg_enum_oid(PG_FUNCTION_ARGS)
111155
{

0 commit comments

Comments
 (0)