Preserve relfilenode of pg_largeobject and its index across pg_upgrade.
Commit 9a974cbcba005256a19991203583a94b4f9a21a9 did this for user tables, but pg_upgrade treats pg_largeobject as a user table, and so needs the same treatment. Without this fix, if you rewrite the pg_largeobject table and then perform an upgrade with pg_upgrade, the table will apparently be empty on the new cluster, while all of your objects will end up with an orphaned file. With this fix, instead of the old cluster's pg_largeobject files ending up orphaned, the original files fro the new cluster do. That's mostly harmless because we expect the table to be empty, but we might want to arrange to remove the as part of the upgrade. Since we're still debating the best way of doing that, I (rhaas) have decided to postpone dealing with that problem and get the basic fix committed. Justin Pryzby, reviewed by Shruthi Gowda and by me. Discussion: http://postgr.es/m/20220701231413.GI13040@telsasoft.com
This commit is contained in:
parent
bf1f4a364d
commit
d498e052b4
@ -3134,7 +3134,7 @@ dumpDatabase(Archive *fout)
|
||||
|
||||
/*
|
||||
* pg_largeobject comes from the old system intact, so set its
|
||||
* relfrozenxids and relminmxids.
|
||||
* relfrozenxids, relminmxids and relfilenode.
|
||||
*/
|
||||
if (dopt->binary_upgrade)
|
||||
{
|
||||
@ -3142,34 +3142,41 @@ dumpDatabase(Archive *fout)
|
||||
PQExpBuffer loFrozenQry = createPQExpBuffer();
|
||||
PQExpBuffer loOutQry = createPQExpBuffer();
|
||||
int i_relfrozenxid,
|
||||
i_relfilenode,
|
||||
i_oid,
|
||||
i_relminmxid;
|
||||
|
||||
/*
|
||||
* pg_largeobject
|
||||
*/
|
||||
if (fout->remoteVersion >= 90300)
|
||||
appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid\n"
|
||||
appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n"
|
||||
"FROM pg_catalog.pg_class\n"
|
||||
"WHERE oid = %u;\n",
|
||||
LargeObjectRelationId);
|
||||
"WHERE oid IN (%u, %u);\n",
|
||||
LargeObjectRelationId, LargeObjectLOidPNIndexId);
|
||||
else
|
||||
appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid\n"
|
||||
appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n"
|
||||
"FROM pg_catalog.pg_class\n"
|
||||
"WHERE oid = %u;\n",
|
||||
LargeObjectRelationId);
|
||||
"WHERE oid IN (%u, %u);\n",
|
||||
LargeObjectRelationId, LargeObjectLOidPNIndexId);
|
||||
|
||||
lo_res = ExecuteSqlQueryForSingleRow(fout, loFrozenQry->data);
|
||||
lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK);
|
||||
|
||||
i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
|
||||
i_relminmxid = PQfnumber(lo_res, "relminmxid");
|
||||
i_relfilenode = PQfnumber(lo_res, "relfilenode");
|
||||
i_oid = PQfnumber(lo_res, "oid");
|
||||
|
||||
appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, preserve values for pg_largeobject and its index\n");
|
||||
for (int i = 0; i < PQntuples(lo_res); ++i)
|
||||
appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n"
|
||||
"SET relfrozenxid = '%u', relminmxid = '%u', relfilenode = '%u'\n"
|
||||
"WHERE oid = %u;\n",
|
||||
atooid(PQgetvalue(lo_res, i, i_relfrozenxid)),
|
||||
atooid(PQgetvalue(lo_res, i, i_relminmxid)),
|
||||
atooid(PQgetvalue(lo_res, i, i_relfilenode)),
|
||||
atooid(PQgetvalue(lo_res, i, i_oid)));
|
||||
|
||||
appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject relfrozenxid and relminmxid\n");
|
||||
appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n"
|
||||
"SET relfrozenxid = '%u', relminmxid = '%u'\n"
|
||||
"WHERE oid = %u;\n",
|
||||
atooid(PQgetvalue(lo_res, 0, i_relfrozenxid)),
|
||||
atooid(PQgetvalue(lo_res, 0, i_relminmxid)),
|
||||
LargeObjectRelationId);
|
||||
ArchiveEntry(fout, nilCatalogId, createDumpId(),
|
||||
ARCHIVE_OPTS(.tag = "pg_largeobject",
|
||||
.description = "pg_largeobject",
|
||||
|
@ -208,6 +208,8 @@ if (defined($ENV{oldinstall}))
|
||||
}
|
||||
}
|
||||
|
||||
$oldnode->safe_psql("regression", "VACUUM FULL pg_largeobject;");
|
||||
|
||||
# In a VPATH build, we'll be started in the source directory, but we want
|
||||
# to run pg_upgrade in the build directory so that any files generated finish
|
||||
# in it, like delete_old_cluster.{sh,bat}.
|
||||
|
Loading…
x
Reference in New Issue
Block a user