55
55
#include "catalog/pg_trigger_d.h"
56
56
#include "catalog/pg_type_d.h"
57
57
#include "common/connect.h"
58
+ #include "common/int.h"
58
59
#include "common/relpath.h"
59
60
#include "compress_io.h"
60
61
#include "dumputils.h"
@@ -92,6 +93,17 @@ typedef struct
92
93
int objsubid; /* subobject (table column #) */
93
94
} SecLabelItem;
94
95
96
+ typedef struct
97
+ {
98
+ Oid oid; /* object OID */
99
+ char relkind; /* object kind */
100
+ RelFileNumber relfilenumber; /* object filenode */
101
+ Oid toast_oid; /* toast table OID */
102
+ RelFileNumber toast_relfilenumber; /* toast table filenode */
103
+ Oid toast_index_oid; /* toast table index OID */
104
+ RelFileNumber toast_index_relfilenumber; /* toast table index filenode */
105
+ } BinaryUpgradeClassOidItem;
106
+
95
107
typedef enum OidOptions
96
108
{
97
109
zeroIsError = 1,
@@ -157,6 +169,10 @@ static int ncomments = 0;
157
169
static SecLabelItem *seclabels = NULL;
158
170
static int nseclabels = 0;
159
171
172
+ /* sorted table of pg_class information for binary upgrade */
173
+ static BinaryUpgradeClassOidItem *binaryUpgradeClassOids = NULL;
174
+ static int nbinaryUpgradeClassOids = 0;
175
+
160
176
/*
161
177
* The default number of rows per INSERT when
162
178
* --inserts is specified without --rows-per-insert
@@ -322,6 +338,7 @@ static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
322
338
static void binary_upgrade_set_type_oids_by_rel(Archive *fout,
323
339
PQExpBuffer upgrade_buffer,
324
340
const TableInfo *tbinfo);
341
+ static void collectBinaryUpgradeClassOids(Archive *fout);
325
342
static void binary_upgrade_set_pg_class_oids(Archive *fout,
326
343
PQExpBuffer upgrade_buffer,
327
344
Oid pg_class_oid);
@@ -971,6 +988,10 @@ main(int argc, char **argv)
971
988
if (!dopt.no_security_labels)
972
989
collectSecLabels(fout);
973
990
991
+ /* For binary upgrade mode, collect required pg_class information. */
992
+ if (dopt.binary_upgrade)
993
+ collectBinaryUpgradeClassOids(fout);
994
+
974
995
/* Lastly, create dummy objects to represent the section boundaries */
975
996
boundaryObjs = createBoundaryObjects();
976
997
@@ -5383,18 +5404,67 @@ binary_upgrade_set_type_oids_by_rel(Archive *fout,
5383
5404
pg_type_oid, false, false);
5384
5405
}
5385
5406
5407
+ /*
5408
+ * bsearch() comparator for BinaryUpgradeClassOidItem
5409
+ */
5410
+ static int
5411
+ BinaryUpgradeClassOidItemCmp(const void *p1, const void *p2)
5412
+ {
5413
+ BinaryUpgradeClassOidItem v1 = *((const BinaryUpgradeClassOidItem *) p1);
5414
+ BinaryUpgradeClassOidItem v2 = *((const BinaryUpgradeClassOidItem *) p2);
5415
+
5416
+ return pg_cmp_u32(v1.oid, v2.oid);
5417
+ }
5418
+
5419
+ /*
5420
+ * collectBinaryUpgradeClassOids
5421
+ *
5422
+ * Construct a table of pg_class information required for
5423
+ * binary_upgrade_set_pg_class_oids(). The table is sorted by OID for speed in
5424
+ * lookup.
5425
+ */
5426
+ static void
5427
+ collectBinaryUpgradeClassOids(Archive *fout)
5428
+ {
5429
+ PGresult *res;
5430
+ const char *query;
5431
+
5432
+ query = "SELECT c.oid, c.relkind, c.relfilenode, c.reltoastrelid, "
5433
+ "ct.relfilenode, i.indexrelid, cti.relfilenode "
5434
+ "FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_index i "
5435
+ "ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
5436
+ "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
5437
+ "LEFT JOIN pg_catalog.pg_class AS cti ON (i.indexrelid = cti.oid) "
5438
+ "ORDER BY c.oid;";
5439
+
5440
+ res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
5441
+
5442
+ nbinaryUpgradeClassOids = PQntuples(res);
5443
+ binaryUpgradeClassOids = (BinaryUpgradeClassOidItem *)
5444
+ pg_malloc(nbinaryUpgradeClassOids * sizeof(BinaryUpgradeClassOidItem));
5445
+
5446
+ for (int i = 0; i < nbinaryUpgradeClassOids; i++)
5447
+ {
5448
+ binaryUpgradeClassOids[i].oid = atooid(PQgetvalue(res, i, 0));
5449
+ binaryUpgradeClassOids[i].relkind = *PQgetvalue(res, i, 1);
5450
+ binaryUpgradeClassOids[i].relfilenumber = atooid(PQgetvalue(res, i, 2));
5451
+ binaryUpgradeClassOids[i].toast_oid = atooid(PQgetvalue(res, i, 3));
5452
+ binaryUpgradeClassOids[i].toast_relfilenumber = atooid(PQgetvalue(res, i, 4));
5453
+ binaryUpgradeClassOids[i].toast_index_oid = atooid(PQgetvalue(res, i, 5));
5454
+ binaryUpgradeClassOids[i].toast_index_relfilenumber = atooid(PQgetvalue(res, i, 6));
5455
+ }
5456
+
5457
+ PQclear(res);
5458
+ }
5459
+
5386
5460
static void
5387
5461
binary_upgrade_set_pg_class_oids(Archive *fout,
5388
5462
PQExpBuffer upgrade_buffer, Oid pg_class_oid)
5389
5463
{
5390
- PQExpBuffer upgrade_query = createPQExpBuffer();
5391
- PGresult *upgrade_res;
5392
- RelFileNumber relfilenumber;
5393
- Oid toast_oid;
5394
- RelFileNumber toast_relfilenumber;
5395
- char relkind;
5396
- Oid toast_index_oid;
5397
- RelFileNumber toast_index_relfilenumber;
5464
+ BinaryUpgradeClassOidItem key = {0};
5465
+ BinaryUpgradeClassOidItem *entry;
5466
+
5467
+ Assert(binaryUpgradeClassOids);
5398
5468
5399
5469
/*
5400
5470
* Preserve the OID and relfilenumber of the table, table's index, table's
@@ -5407,35 +5477,16 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
5407
5477
* by the new backend, so we can copy the files during binary upgrade
5408
5478
* without worrying about this case.
5409
5479
*/
5410
- appendPQExpBuffer(upgrade_query,
5411
- "SELECT c.relkind, c.relfilenode, c.reltoastrelid, ct.relfilenode AS toast_relfilenode, i.indexrelid, cti.relfilenode AS toast_index_relfilenode "
5412
- "FROM pg_catalog.pg_class c LEFT JOIN "
5413
- "pg_catalog.pg_index i ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
5414
- "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
5415
- "LEFT JOIN pg_catalog.pg_class AS cti ON (i.indexrelid = cti.oid) "
5416
- "WHERE c.oid = '%u'::pg_catalog.oid;",
5417
- pg_class_oid);
5418
-
5419
- upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5420
-
5421
- relkind = *PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "relkind"));
5422
-
5423
- relfilenumber = atooid(PQgetvalue(upgrade_res, 0,
5424
- PQfnumber(upgrade_res, "relfilenode")));
5425
- toast_oid = atooid(PQgetvalue(upgrade_res, 0,
5426
- PQfnumber(upgrade_res, "reltoastrelid")));
5427
- toast_relfilenumber = atooid(PQgetvalue(upgrade_res, 0,
5428
- PQfnumber(upgrade_res, "toast_relfilenode")));
5429
- toast_index_oid = atooid(PQgetvalue(upgrade_res, 0,
5430
- PQfnumber(upgrade_res, "indexrelid")));
5431
- toast_index_relfilenumber = atooid(PQgetvalue(upgrade_res, 0,
5432
- PQfnumber(upgrade_res, "toast_index_relfilenode")));
5480
+ key.oid = pg_class_oid;
5481
+ entry = bsearch(&key, binaryUpgradeClassOids, nbinaryUpgradeClassOids,
5482
+ sizeof(BinaryUpgradeClassOidItem),
5483
+ BinaryUpgradeClassOidItemCmp);
5433
5484
5434
5485
appendPQExpBufferStr(upgrade_buffer,
5435
5486
"\n-- For binary upgrade, must preserve pg_class oids and relfilenodes\n");
5436
5487
5437
- if (relkind != RELKIND_INDEX &&
5438
- relkind != RELKIND_PARTITIONED_INDEX)
5488
+ if (entry-> relkind != RELKIND_INDEX &&
5489
+ entry-> relkind != RELKIND_PARTITIONED_INDEX)
5439
5490
{
5440
5491
appendPQExpBuffer(upgrade_buffer,
5441
5492
"SELECT pg_catalog.binary_upgrade_set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
@@ -5446,32 +5497,33 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
5446
5497
* partitioned tables have a relfilenumber, which should not be
5447
5498
* preserved when upgrading.
5448
5499
*/
5449
- if (RelFileNumberIsValid(relfilenumber) && relkind != RELKIND_PARTITIONED_TABLE)
5500
+ if (RelFileNumberIsValid(entry->relfilenumber) &&
5501
+ entry->relkind != RELKIND_PARTITIONED_TABLE)
5450
5502
appendPQExpBuffer(upgrade_buffer,
5451
5503
"SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
5452
- relfilenumber);
5504
+ entry-> relfilenumber);
5453
5505
5454
5506
/*
5455
5507
* In a pre-v12 database, partitioned tables might be marked as having
5456
5508
* toast tables, but we should ignore them if so.
5457
5509
*/
5458
- if (OidIsValid(toast_oid) &&
5459
- relkind != RELKIND_PARTITIONED_TABLE)
5510
+ if (OidIsValid(entry-> toast_oid) &&
5511
+ entry-> relkind != RELKIND_PARTITIONED_TABLE)
5460
5512
{
5461
5513
appendPQExpBuffer(upgrade_buffer,
5462
5514
"SELECT pg_catalog.binary_upgrade_set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
5463
- toast_oid);
5515
+ entry-> toast_oid);
5464
5516
appendPQExpBuffer(upgrade_buffer,
5465
5517
"SELECT pg_catalog.binary_upgrade_set_next_toast_relfilenode('%u'::pg_catalog.oid);\n",
5466
- toast_relfilenumber);
5518
+ entry-> toast_relfilenumber);
5467
5519
5468
5520
/* every toast table has an index */
5469
5521
appendPQExpBuffer(upgrade_buffer,
5470
5522
"SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5471
- toast_index_oid);
5523
+ entry-> toast_index_oid);
5472
5524
appendPQExpBuffer(upgrade_buffer,
5473
5525
"SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5474
- toast_index_relfilenumber);
5526
+ entry-> toast_index_relfilenumber);
5475
5527
}
5476
5528
}
5477
5529
else
@@ -5482,14 +5534,10 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
5482
5534
pg_class_oid);
5483
5535
appendPQExpBuffer(upgrade_buffer,
5484
5536
"SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5485
- relfilenumber);
5537
+ entry-> relfilenumber);
5486
5538
}
5487
5539
5488
- PQclear(upgrade_res);
5489
-
5490
5540
appendPQExpBufferChar(upgrade_buffer, '\n');
5491
-
5492
- destroyPQExpBuffer(upgrade_query);
5493
5541
}
5494
5542
5495
5543
/*
0 commit comments