PGresult *lo_res;
PQExpBuffer loFrozenQry = createPQExpBuffer();
PQExpBuffer loOutQry = createPQExpBuffer();
- PQExpBuffer loVacQry = createPQExpBuffer();
+ PQExpBuffer loHorizonQry = createPQExpBuffer();
int i_relfrozenxid,
i_relfilenode,
i_oid,
i_relfilenode = PQfnumber(lo_res, "relfilenode");
i_oid = PQfnumber(lo_res, "oid");
- appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject relfrozenxid and relminmxid\n");
- appendPQExpBufferStr(loVacQry, "\n-- For binary upgrade, preserve pg_largeobject and index relfilenodes\n");
+ appendPQExpBufferStr(loHorizonQry, "\n-- For binary upgrade, set pg_largeobject relfrozenxid and relminmxid\n");
+ appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, preserve pg_largeobject and index relfilenodes\n");
for (int i = 0; i < PQntuples(lo_res); ++i)
{
Oid oid;
RelFileNumber relfilenumber;
- appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n"
+ appendPQExpBuffer(loHorizonQry, "UPDATE pg_catalog.pg_class\n"
"SET relfrozenxid = '%u', relminmxid = '%u'\n"
"WHERE oid = %u;\n",
atooid(PQgetvalue(lo_res, i, i_relfrozenxid)),
relfilenumber = atooid(PQgetvalue(lo_res, i, i_relfilenode));
if (oid == LargeObjectRelationId)
- appendPQExpBuffer(loVacQry,
+ appendPQExpBuffer(loOutQry,
"SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
relfilenumber);
else if (oid == LargeObjectLOidPNIndexId)
- appendPQExpBuffer(loVacQry,
+ appendPQExpBuffer(loOutQry,
"SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
relfilenumber);
}
- appendPQExpBufferStr(loVacQry,
+ appendPQExpBufferStr(loOutQry,
"TRUNCATE pg_catalog.pg_largeobject;\n");
- appendPQExpBufferStr(loOutQry, loVacQry->data);
+ appendPQExpBufferStr(loOutQry, loHorizonQry->data);
ArchiveEntry(fout, nilCatalogId, createDumpId(),
ARCHIVE_OPTS(.tag = "pg_largeobject",
PQclear(lo_res);
destroyPQExpBuffer(loFrozenQry);
+ destroyPQExpBuffer(loHorizonQry);
destroyPQExpBuffer(loOutQry);
- destroyPQExpBuffer(loVacQry);
}
PQclear(res);
],
'dump before running pg_upgrade');
+# Also record the relfrozenxid and relminmxid horizons.
+my $horizon_query = <<EOM;
+SELECT
+ c.oid::regclass, c.relfrozenxid, c.relminmxid
+FROM
+ pg_class c, pg_namespace n
+WHERE
+ c.relnamespace = n.oid AND
+ ((n.nspname !~ '^pg_temp_' AND n.nspname !~ '^pg_toast_temp_' AND
+ n.nspname NOT IN ('pg_catalog', 'information_schema', 'binary_upgrade',
+ 'pg_toast'))
+ OR (n.nspname = 'pg_catalog' AND relname IN ('pg_largeobject')))
+EOM
+$horizon_query =~ s/\s+/ /g; # run it together on one line
+$newnode->command_ok(
+ [
+ 'psql', '-At', '-d', $oldnode->connstr('postgres'),
+ '-o', "$tempdir/horizon1.txt", '-c', $horizon_query,
+ ],
+ 'horizons before running pg_upgrade');
+
# After dumping, update references to the old source tree's regress.so
# to point to the new tree.
if (defined($ENV{oldinstall}))
],
'dump after running pg_upgrade');
+# And second record of horizons as well.
+$newnode->command_ok(
+ [
+ 'psql', '-At', '-d', $newnode->connstr('postgres'),
+ '-o', "$tempdir/horizon2.txt", '-c', $horizon_query,
+ ],
+ 'horizons after running pg_upgrade');
+
# Compare the two dumps, there should be no differences.
my $compare_res = compare("$tempdir/dump1.sql", "$tempdir/dump2.sql");
is($compare_res, 0, 'old and new dumps match after pg_upgrade');
print "=== EOF ===\n";
}
+# Compare the horizons, there should be no differences.
+$compare_res = compare("$tempdir/horizon1.txt", "$tempdir/horizon2.txt");
+is($compare_res, 0, 'old and new horizons match after pg_upgrade');
+
+# Provide more context if the horizons do not match.
+if ($compare_res != 0)
+{
+ my ($stdout, $stderr) =
+ run_command([ 'diff', "$tempdir/horizon1.txt", "$tempdir/horizon2.txt" ]);
+ print "=== diff of $tempdir/horizon1.txt and $tempdir/horizon2.txt\n";
+ print "=== stdout ===\n";
+ print $stdout;
+ print "=== stderr ===\n";
+ print $stderr;
+ print "=== EOF ===\n";
+}
+
done_testing();