1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

Create a "relation mapping" infrastructure to support changing the relfilenodes

of shared or nailed system catalogs.  This has two key benefits:

* The new CLUSTER-based VACUUM FULL can be applied safely to all catalogs.

* We no longer have to use an unsafe reindex-in-place approach for reindexing
  shared catalogs.

CLUSTER on nailed catalogs now works too, although I left it disabled on
shared catalogs because the resulting pg_index.indisclustered update would
only be visible in one database.

Since reindexing shared system catalogs is now fully transactional and
crash-safe, the former special cases in REINDEX behavior have been removed;
shared catalogs are treated the same as non-shared.

This commit does not do anything about the recently-discussed problem of
deadlocks between VACUUM FULL/CLUSTER on a system catalog and other
concurrent queries; will address that in a separate patch.  As a stopgap,
parallel_schedule has been tweaked to run vacuum.sql by itself, to avoid
such failures during the regression tests.
This commit is contained in:
Tom Lane
2010-02-07 20:48:13 +00:00
parent 7fc30c488f
commit b9b8831ad6
54 changed files with 2316 additions and 585 deletions

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.282 2010/01/24 21:49:17 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.283 2010/02/07 20:48:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -48,6 +48,7 @@
#include "utils/inval.h"
#include "utils/memutils.h"
#include "utils/relcache.h"
#include "utils/relmapper.h"
#include "utils/snapmgr.h"
#include "pg_trace.h"
@ -250,7 +251,7 @@ static void AbortTransaction(void);
static void AtAbort_Memory(void);
static void AtCleanup_Memory(void);
static void AtAbort_ResourceOwner(void);
static void AtCommit_LocalCache(void);
static void AtCCI_LocalCache(void);
static void AtCommit_Memory(void);
static void AtStart_Cache(void);
static void AtStart_Memory(void);
@ -703,7 +704,7 @@ CommandCounterIncrement(void)
* read-only command. (But see hacks in inval.c to make real sure we
* don't think a command that queued inval messages was read-only.)
*/
AtCommit_LocalCache();
AtCCI_LocalCache();
}
/*
@ -1095,11 +1096,19 @@ cleanup:
/*
* AtCommit_LocalCache
* AtCCI_LocalCache
*/
static void
AtCommit_LocalCache(void)
AtCCI_LocalCache(void)
{
/*
* Make any pending relation map changes visible. We must do this
* before processing local sinval messages, so that the map changes
* will get reflected into the relcache when relcache invals are
* processed.
*/
AtCCI_RelationMap();
/*
* Make catalog changes visible to me for the next command.
*/
@ -1734,6 +1743,9 @@ CommitTransaction(void)
/* Prevent cancel/die interrupt while cleaning up */
HOLD_INTERRUPTS();
/* Commit updates to the relation map --- do this as late as possible */
AtEOXact_RelationMap(true);
/*
* set the current transaction state information appropriately during
* commit processing
@ -1980,6 +1992,7 @@ PrepareTransaction(void)
AtPrepare_Locks();
AtPrepare_PgStat();
AtPrepare_MultiXact();
AtPrepare_RelationMap();
/*
* Here is where we really truly prepare.
@ -2148,10 +2161,11 @@ AbortTransaction(void)
/*
* do abort processing
*/
AfterTriggerEndXact(false);
AfterTriggerEndXact(false); /* 'false' means it's abort */
AtAbort_Portals();
AtEOXact_LargeObject(false); /* 'false' means it's abort */
AtEOXact_LargeObject(false);
AtAbort_Notify();
AtEOXact_RelationMap(false);
/*
* Advertise the fact that we aborted in pg_clog (assuming that we got as
@ -4625,11 +4639,18 @@ xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
SharedInvalidationMessage *msg = &msgs[i];
if (msg->id >= 0)
appendStringInfo(buf, "catcache id%d ", msg->id);
appendStringInfo(buf, " catcache %d", msg->id);
else if (msg->id == SHAREDINVALCATALOG_ID)
appendStringInfo(buf, " catalog %u", msg->cat.catId);
else if (msg->id == SHAREDINVALRELCACHE_ID)
appendStringInfo(buf, "relcache ");
appendStringInfo(buf, " relcache %u", msg->rc.relId);
/* remaining cases not expected, but print something anyway */
else if (msg->id == SHAREDINVALSMGR_ID)
appendStringInfo(buf, "smgr ");
appendStringInfo(buf, " smgr");
else if (msg->id == SHAREDINVALRELMAP_ID)
appendStringInfo(buf, " relmap");
else
appendStringInfo(buf, " unknown id %d", msg->id);
}
}
}