aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/freespace/freespace.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2008-10-31 15:05:00 +0000
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2008-10-31 15:05:00 +0000
commit19c8dc839b64a43958f08108b85ce8ca98d06a8b (patch)
treebe6bff739a33bd11e4915f47f30038840d397cd5 /src/backend/storage/freespace/freespace.c
parent29077051deae30b7704a3e3f2cf7d0a7e3a4130a (diff)
downloadpostgresql-19c8dc839b64a43958f08108b85ce8ca98d06a8b.tar.gz
postgresql-19c8dc839b64a43958f08108b85ce8ca98d06a8b.zip
Unite ReadBufferWithFork, ReadBufferWithStrategy, and ZeroOrReadBuffer
functions into one ReadBufferExtended function, that takes the strategy and mode as argument. There's three modes, RBM_NORMAL which is the default used by plain ReadBuffer(), RBM_ZERO, which replaces ZeroOrReadBuffer, and a new mode RBM_ZERO_ON_ERROR, which allows callers to read corrupt pages without throwing an error. The FSM needs the new mode to recover from corrupt pages, which could happend if we crash after extending an FSM file, and the new page is "torn". Add fork number to some error messages in bufmgr.c, that still lacked it.
Diffstat (limited to 'src/backend/storage/freespace/freespace.c')
-rw-r--r--src/backend/storage/freespace/freespace.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c
index 9872e5c7222..724e87fa204 100644
--- a/src/backend/storage/freespace/freespace.c
+++ b/src/backend/storage/freespace/freespace.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.64 2008/10/01 14:59:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.65 2008/10/31 15:05:00 heikki Exp $
*
*
* NOTES:
@@ -504,6 +504,7 @@ static Buffer
fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
{
BlockNumber blkno = fsm_logical_to_physical(addr);
+ Buffer buf;
RelationOpenSmgr(rel);
@@ -518,7 +519,18 @@ fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
else
return InvalidBuffer;
}
- return ReadBufferWithFork(rel, FSM_FORKNUM, blkno);
+
+ /*
+ * Use ZERO_ON_ERROR mode, and initialize the page if necessary. The FSM
+ * information is not accurate anyway, so it's better to clear corrupt
+ * pages than error out. Since the FSM changes are not WAL-logged, the
+ * so-called torn page problem on crash can lead to pages with corrupt
+ * headers, for example.
+ */
+ buf = ReadBufferExtended(rel, FSM_FORKNUM, blkno, RBM_ZERO_ON_ERROR, NULL);
+ if (PageIsNew(BufferGetPage(buf)))
+ PageInit(BufferGetPage(buf), BLCKSZ, 0);
+ return buf;
}
/*
@@ -779,23 +791,18 @@ fsm_redo_truncate(xl_fsm_truncate *xlrec)
* replay of the smgr truncation record to remove completely unused
* pages.
*/
- buf = XLogReadBufferWithFork(xlrec->node, FSM_FORKNUM, fsmblk, false);
+ buf = XLogReadBufferExtended(xlrec->node, FSM_FORKNUM, fsmblk,
+ RBM_ZERO_ON_ERROR);
if (BufferIsValid(buf))
{
- fsm_truncate_avail(BufferGetPage(buf), first_removed_slot);
+ Page page = BufferGetPage(buf);
+
+ if (PageIsNew(page))
+ PageInit(page, BLCKSZ, 0);
+ fsm_truncate_avail(page, first_removed_slot);
MarkBufferDirty(buf);
UnlockReleaseBuffer(buf);
}
- else
- {
- /*
- * The page doesn't exist. Because FSM extensions are not WAL-logged,
- * it's normal to have a truncation record for a page that doesn't
- * exist. Tell xlogutils.c not to PANIC at the end of recovery
- * because of the missing page
- */
- XLogTruncateRelation(xlrec->node, FSM_FORKNUM, fsmblk);
- }
}
void