Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9936f14

Browse files
committed
Repair pg_upgrade's failure to preserve relfrozenxid for matviews.
This oversight led to data corruption in matviews, manifesting as"could not access status of transaction" before our most recent releases,and "found xmin from before relfrozenxid" errors since then.The proximate cause of the problem seems to have been confusion betweenthe task of preserving dropped-column status and the task of preservingfrozenxid status. Those are required for distinct sets of relkinds,and the reasoning was entirely undocumented in the source code. In hopesof forestalling future errors of the same kind, try to improve thecommentary in this area.In passing, also improve the remarkably unhelpful comments aroundpg_upgrade's set_frozenxids(). That's not actually buggy AFAICS,but good luck figuring out what it does from the old comments.Per report from Claudio Freire. It appears that bug #14852 from AlexeyErmakov is an earlier report of the same issue, and there may be othercases that we failed to identify at the time.Patch by me based on analysis by Andres Freund. The bug dates backto the introduction of matviews, so back-patch to all supported branches.Discussion:https://postgr.es/m/CAGTBQpbrY9CdRGGhyBZ9yqY4jWaGC85rUF4X+R7d-aim=mBNsw@mail.gmail.comDiscussion:https://postgr.es/m/20171013115320.28049.86457@wrigleys.postgresql.org
1 parent340d63b commit9936f14

File tree

2 files changed

+47
-13
lines changed

2 files changed

+47
-13
lines changed

‎src/bin/pg_dump/pg_dump.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14278,6 +14278,13 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1427814278
* column order. That also means we have to take care about setting
1427914279
* attislocal correctly, plus fix up any inherited CHECK constraints.
1428014280
* Analogously, we set up typed tables using ALTER TABLE / OF here.
14281+
*
14282+
* We process foreign tables here, even though they lack heap storage,
14283+
* because they can participate in inheritance relationships and we
14284+
* want this stuff to be consistent across the inheritance tree. We
14285+
* exclude indexes, toast tables, sequences and matviews, even though
14286+
* they have storage, because we don't support altering or dropping
14287+
* columns in them, nor can they be part of inheritance trees.
1428114288
*/
1428214289
if (dopt->binary_upgrade&&
1428314290
(tbinfo->relkind==RELKIND_RELATION||
@@ -14367,7 +14374,19 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1436714374
fmtId(tbinfo->dobj.name),
1436814375
tbinfo->reloftype);
1436914376
}
14377+
}
1437014378

14379+
/*
14380+
* In binary_upgrade mode, arrange to restore the old relfrozenxid and
14381+
* relminmxid of all vacuumable relations. (While vacuum.c processes
14382+
* TOAST tables semi-independently, here we see them only as children
14383+
* of other relations; so this "if" lacks RELKIND_TOASTVALUE, and the
14384+
* child toast table is handled below.)
14385+
*/
14386+
if (dopt->binary_upgrade&&
14387+
(tbinfo->relkind==RELKIND_RELATION||
14388+
tbinfo->relkind==RELKIND_MATVIEW))
14389+
{
1437114390
appendPQExpBufferStr(q,"\n-- For binary upgrade, set heap's relfrozenxid and relminmxid\n");
1437214391
appendPQExpBuffer(q,"UPDATE pg_catalog.pg_class\n"
1437314392
"SET relfrozenxid = '%u', relminmxid = '%u'\n"
@@ -14378,7 +14397,10 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1437814397

1437914398
if (tbinfo->toast_oid)
1438014399
{
14381-
/* We preserve the toast oids, so we can use it during restore */
14400+
/*
14401+
* The toast table will have the same OID at restore, so we
14402+
* can safely target it by OID.
14403+
*/
1438214404
appendPQExpBufferStr(q,"\n-- For binary upgrade, set toast's relfrozenxid and relminmxid\n");
1438314405
appendPQExpBuffer(q,"UPDATE pg_catalog.pg_class\n"
1438414406
"SET relfrozenxid = '%u', relminmxid = '%u'\n"
@@ -14392,7 +14414,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1439214414
* In binary_upgrade mode, restore matviews' populated status by
1439314415
* poking pg_class directly. This is pretty ugly, but we can't use
1439414416
* REFRESH MATERIALIZED VIEW since it's possible that some underlying
14395-
* matview is not populated even though this matview is.
14417+
* matview is not populated even though this matview is; in any case,
14418+
* we want to transfer the matview's heap storage, not run REFRESH.
1439614419
*/
1439714420
if (dopt->binary_upgrade&&tbinfo->relkind==RELKIND_MATVIEW&&
1439814421
tbinfo->relispopulated)

‎src/bin/pg_upgrade/pg_upgrade.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -272,13 +272,13 @@ static void
272272
prepare_new_databases(void)
273273
{
274274
/*
275-
* We set autovacuum_freeze_max_age to its maximum value so autovacuum
276-
* does not launch here and delete clog files, before the frozen xids are
277-
* set.
275+
* Before we restore anything, set frozenxids of initdb-created tables.
278276
*/
279-
280277
set_frozenxids(false);
281278

279+
/*
280+
* Now restore global objects (roles and tablespaces).
281+
*/
282282
prep_status("Restoring global objects in the new cluster");
283283

284284
/*
@@ -496,14 +496,25 @@ copy_clog_xlog_xid(void)
496496
/*
497497
*set_frozenxids()
498498
*
499-
*We have frozen all xids, so set datfrozenxid, relfrozenxid, and
500-
*relminmxid to be the old cluster's xid counter, which we just set
501-
*in the new cluster. User-table frozenxid and minmxid values will
502-
*be set by pg_dump --binary-upgrade, but objects not set by the pg_dump
503-
*must have proper frozen counters.
499+
* This is called on the new cluster before we restore anything, with
500+
* minmxid_only = false. Its purpose is to ensure that all initdb-created
501+
* vacuumable tables have relfrozenxid/relminmxid matching the old cluster's
502+
* xid/mxid counters. We also initialize the datfrozenxid/datminmxid of the
503+
* built-in databases to match.
504+
*
505+
* As we create user tables later, their relfrozenxid/relminmxid fields will
506+
* be restored properly by the binary-upgrade restore script. Likewise for
507+
* user-database datfrozenxid/datminmxid. However, if we're upgrading from a
508+
* pre-9.3 database, which does not store per-table or per-DB minmxid, then
509+
* the relminmxid/datminmxid values filled in by the restore script will just
510+
* be zeroes.
511+
*
512+
* Hence, with a pre-9.3 source database, a second call occurs after
513+
* everything is restored, with minmxid_only = true. This pass will
514+
* initialize all tables and databases, both those made by initdb and user
515+
* objects, with the desired minmxid value. frozenxid values are left alone.
504516
*/
505-
static
506-
void
517+
staticvoid
507518
set_frozenxids(boolminmxid_only)
508519
{
509520
intdbnum;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp