aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/cache
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-02-09 21:43:30 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2010-02-09 21:43:30 +0000
commitcbe9d6beb4ae1cb20c08cab29b534be4923b6768 (patch)
treea9476492cd8c7eda7718f95b0ad5a45d41e55a3a /src/backend/utils/cache
parent79647eed86cc972e80ea165dcb0b7f6fef876169 (diff)
downloadpostgresql-cbe9d6beb4ae1cb20c08cab29b534be4923b6768.tar.gz
postgresql-cbe9d6beb4ae1cb20c08cab29b534be4923b6768.zip
Fix up rickety handling of relation-truncation interlocks.
Move rd_targblock, rd_fsm_nblocks, and rd_vm_nblocks from relcache to the smgr relation entries, so that they will get reset to InvalidBlockNumber whenever an smgr-level flush happens. Because we now send smgr invalidation messages immediately (not at end of transaction) when a relation truncation occurs, this ensures that other backends will reset their values before they next access the relation. We no longer need the unreliable assumption that a VACUUM that's doing a truncation will hold its AccessExclusive lock until commit --- in fact, we can intentionally release that lock as soon as we've completed the truncation. This patch therefore reverts (most of) Alvaro's patch of 2009-11-10, as well as my marginal hacking on it yesterday. We can also get rid of assorted no-longer-needed relcache flushes, which are far more expensive than an smgr flush because they kill a lot more state. In passing this patch fixes smgr_redo's failure to perform visibility-map truncation, and cleans up some rather dubious assumptions in freespace.c and visibilitymap.c about when rd_fsm_nblocks and rd_vm_nblocks can be out of date.
Diffstat (limited to 'src/backend/utils/cache')
-rw-r--r--src/backend/utils/cache/relcache.c39
1 files changed, 4 insertions, 35 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 6137b096772..0492f73e2e0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.304 2010/02/08 05:53:55 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.305 2010/02/09 21:43:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -328,13 +328,6 @@ AllocateRelationDesc(Form_pg_class relp)
*/
relation = (Relation) palloc0(sizeof(RelationData));
- /*
- * clear fields of reldesc that should initialize to something non-zero
- */
- relation->rd_targblock = InvalidBlockNumber;
- relation->rd_fsm_nblocks = InvalidBlockNumber;
- relation->rd_vm_nblocks = InvalidBlockNumber;
-
/* make sure relation is marked as having no open file yet */
relation->rd_smgr = NULL;
@@ -1413,9 +1406,6 @@ formrdesc(const char *relationName, Oid relationReltype,
* allocate new relation desc, clear all fields of reldesc
*/
relation = (Relation) palloc0(sizeof(RelationData));
- relation->rd_targblock = InvalidBlockNumber;
- relation->rd_fsm_nblocks = InvalidBlockNumber;
- relation->rd_vm_nblocks = InvalidBlockNumber;
/* make sure relation is marked as having no open file yet */
relation->rd_smgr = NULL;
@@ -1714,14 +1704,7 @@ RelationReloadIndexInfo(Relation relation)
/* Should be closed at smgr level */
Assert(relation->rd_smgr == NULL);
- /*
- * Must reset targblock, fsm_nblocks and vm_nblocks in case rel was
- * truncated
- */
- relation->rd_targblock = InvalidBlockNumber;
- relation->rd_fsm_nblocks = InvalidBlockNumber;
- relation->rd_vm_nblocks = InvalidBlockNumber;
- /* Must free any AM cached data, too */
+ /* Must free any AM cached data upon relcache flush */
if (relation->rd_amcache)
pfree(relation->rd_amcache);
relation->rd_amcache = NULL;
@@ -1867,11 +1850,8 @@ RelationClearRelation(Relation relation, bool rebuild)
/*
* Never, never ever blow away a nailed-in system relation, because we'd
- * be unable to recover. However, we must reset rd_targblock, in case we
- * got called because of a relation cache flush that was triggered by
- * VACUUM. Likewise reset the fsm and vm size info. Also, redo
- * RelationInitPhysicalAddr in case it is a mapped relation whose mapping
- * changed.
+ * be unable to recover. However, we must redo RelationInitPhysicalAddr
+ * in case it is a mapped relation whose mapping changed.
*
* If it's a nailed index, then we need to re-read the pg_class row to see
* if its relfilenode changed. We can't necessarily do that here, because
@@ -1882,10 +1862,6 @@ RelationClearRelation(Relation relation, bool rebuild)
*/
if (relation->rd_isnailed)
{
- relation->rd_targblock = InvalidBlockNumber;
- relation->rd_fsm_nblocks = InvalidBlockNumber;
- relation->rd_vm_nblocks = InvalidBlockNumber;
- /* We must recalculate physical address in case it changed */
RelationInitPhysicalAddr(relation);
if (relation->rd_rel->relkind == RELKIND_INDEX)
@@ -2502,10 +2478,6 @@ RelationBuildLocalRelation(const char *relname,
*/
rel = (Relation) palloc0(sizeof(RelationData));
- rel->rd_targblock = InvalidBlockNumber;
- rel->rd_fsm_nblocks = InvalidBlockNumber;
- rel->rd_vm_nblocks = InvalidBlockNumber;
-
/* make sure relation is marked as having no open file yet */
rel->rd_smgr = NULL;
@@ -4169,9 +4141,6 @@ load_relcache_init_file(bool shared)
* Reset transient-state fields in the relcache entry
*/
rel->rd_smgr = NULL;
- rel->rd_targblock = InvalidBlockNumber;
- rel->rd_fsm_nblocks = InvalidBlockNumber;
- rel->rd_vm_nblocks = InvalidBlockNumber;
if (rel->rd_isnailed)
rel->rd_refcnt = 1;
else