mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-03 04:26:52 +02:00
Fix brown paper bag bug in bbe08b8869
.
We must issue the TRUNCATE command first and update relfrozenxid and relminmxid afterward; otherwise, TRUNCATE overwrites the previously-set values. Add a test case like I should have done the first time. Per buildfarm report from TestUpgradeXversion.pm, by way of Tom Lane.
This commit is contained in:
parent
e6e804aa27
commit
5c9ea19b79
@ -3141,7 +3141,7 @@ dumpDatabase(Archive *fout)
|
|||||||
PGresult *lo_res;
|
PGresult *lo_res;
|
||||||
PQExpBuffer loFrozenQry = createPQExpBuffer();
|
PQExpBuffer loFrozenQry = createPQExpBuffer();
|
||||||
PQExpBuffer loOutQry = createPQExpBuffer();
|
PQExpBuffer loOutQry = createPQExpBuffer();
|
||||||
PQExpBuffer loVacQry = createPQExpBuffer();
|
PQExpBuffer loHorizonQry = createPQExpBuffer();
|
||||||
int i_relfrozenxid,
|
int i_relfrozenxid,
|
||||||
i_relfilenode,
|
i_relfilenode,
|
||||||
i_oid,
|
i_oid,
|
||||||
@ -3168,14 +3168,14 @@ dumpDatabase(Archive *fout)
|
|||||||
i_relfilenode = PQfnumber(lo_res, "relfilenode");
|
i_relfilenode = PQfnumber(lo_res, "relfilenode");
|
||||||
i_oid = PQfnumber(lo_res, "oid");
|
i_oid = PQfnumber(lo_res, "oid");
|
||||||
|
|
||||||
appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject relfrozenxid and relminmxid\n");
|
appendPQExpBufferStr(loHorizonQry, "\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(loOutQry, "\n-- For binary upgrade, preserve pg_largeobject and index relfilenodes\n");
|
||||||
for (int i = 0; i < PQntuples(lo_res); ++i)
|
for (int i = 0; i < PQntuples(lo_res); ++i)
|
||||||
{
|
{
|
||||||
Oid oid;
|
Oid oid;
|
||||||
Oid relfilenode;
|
Oid relfilenode;
|
||||||
|
|
||||||
appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n"
|
appendPQExpBuffer(loHorizonQry, "UPDATE pg_catalog.pg_class\n"
|
||||||
"SET relfrozenxid = '%u', relminmxid = '%u'\n"
|
"SET relfrozenxid = '%u', relminmxid = '%u'\n"
|
||||||
"WHERE oid = %u;\n",
|
"WHERE oid = %u;\n",
|
||||||
atooid(PQgetvalue(lo_res, i, i_relfrozenxid)),
|
atooid(PQgetvalue(lo_res, i, i_relfrozenxid)),
|
||||||
@ -3186,18 +3186,18 @@ dumpDatabase(Archive *fout)
|
|||||||
relfilenode = atooid(PQgetvalue(lo_res, i, i_relfilenode));
|
relfilenode = atooid(PQgetvalue(lo_res, i, i_relfilenode));
|
||||||
|
|
||||||
if (oid == LargeObjectRelationId)
|
if (oid == LargeObjectRelationId)
|
||||||
appendPQExpBuffer(loVacQry,
|
appendPQExpBuffer(loOutQry,
|
||||||
"SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
|
"SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
|
||||||
relfilenode);
|
relfilenode);
|
||||||
else if (oid == LargeObjectLOidPNIndexId)
|
else if (oid == LargeObjectLOidPNIndexId)
|
||||||
appendPQExpBuffer(loVacQry,
|
appendPQExpBuffer(loOutQry,
|
||||||
"SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
|
"SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
|
||||||
relfilenode);
|
relfilenode);
|
||||||
}
|
}
|
||||||
|
|
||||||
appendPQExpBufferStr(loVacQry,
|
appendPQExpBufferStr(loOutQry,
|
||||||
"TRUNCATE pg_catalog.pg_largeobject;\n");
|
"TRUNCATE pg_catalog.pg_largeobject;\n");
|
||||||
appendPQExpBufferStr(loOutQry, loVacQry->data);
|
appendPQExpBufferStr(loOutQry, loHorizonQry->data);
|
||||||
|
|
||||||
ArchiveEntry(fout, nilCatalogId, createDumpId(),
|
ArchiveEntry(fout, nilCatalogId, createDumpId(),
|
||||||
ARCHIVE_OPTS(.tag = "pg_largeobject",
|
ARCHIVE_OPTS(.tag = "pg_largeobject",
|
||||||
@ -3208,8 +3208,8 @@ dumpDatabase(Archive *fout)
|
|||||||
PQclear(lo_res);
|
PQclear(lo_res);
|
||||||
|
|
||||||
destroyPQExpBuffer(loFrozenQry);
|
destroyPQExpBuffer(loFrozenQry);
|
||||||
|
destroyPQExpBuffer(loHorizonQry);
|
||||||
destroyPQExpBuffer(loOutQry);
|
destroyPQExpBuffer(loOutQry);
|
||||||
destroyPQExpBuffer(loVacQry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
|
@ -161,6 +161,27 @@ $newnode->command_ok(
|
|||||||
],
|
],
|
||||||
'dump before running pg_upgrade');
|
'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
|
# After dumping, update references to the old source tree's regress.so
|
||||||
# to point to the new tree.
|
# to point to the new tree.
|
||||||
if (defined($ENV{oldinstall}))
|
if (defined($ENV{oldinstall}))
|
||||||
@ -294,6 +315,14 @@ $newnode->command_ok(
|
|||||||
],
|
],
|
||||||
'dump after running pg_upgrade');
|
'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.
|
# Compare the two dumps, there should be no differences.
|
||||||
my $compare_res = compare("$tempdir/dump1.sql", "$tempdir/dump2.sql");
|
my $compare_res = compare("$tempdir/dump1.sql", "$tempdir/dump2.sql");
|
||||||
is($compare_res, 0, 'old and new dumps match after pg_upgrade');
|
is($compare_res, 0, 'old and new dumps match after pg_upgrade');
|
||||||
@ -311,4 +340,21 @@ if ($compare_res != 0)
|
|||||||
print "=== EOF ===\n";
|
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();
|
done_testing();
|
||||||
|
Loading…
Reference in New Issue
Block a user