aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlogutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/transam/xlogutils.c')
-rw-r--r--src/backend/access/transam/xlogutils.c59
1 files changed, 37 insertions, 22 deletions
diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c
index 3e2d5046da6..59124e349e4 100644
--- a/src/backend/access/transam/xlogutils.c
+++ b/src/backend/access/transam/xlogutils.c
@@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/xlogutils.c,v 1.57 2008/07/13 20:45:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlogutils.c,v 1.58 2008/08/11 11:05:10 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -37,6 +37,7 @@
typedef struct xl_invalid_page_key
{
RelFileNode node; /* the relation */
+ ForkNumber forkno; /* the fork number */
BlockNumber blkno; /* the page */
} xl_invalid_page_key;
@@ -51,7 +52,8 @@ static HTAB *invalid_page_tab = NULL;
/* Log a reference to an invalid page */
static void
-log_invalid_page(RelFileNode node, BlockNumber blkno, bool present)
+log_invalid_page(RelFileNode node, ForkNumber forkno, BlockNumber blkno,
+ bool present)
{
xl_invalid_page_key key;
xl_invalid_page *hentry;
@@ -63,11 +65,11 @@ log_invalid_page(RelFileNode node, BlockNumber blkno, bool present)
* something about the XLOG record that generated the reference).
*/
if (present)
- elog(DEBUG1, "page %u of relation %u/%u/%u is uninitialized",
- blkno, node.spcNode, node.dbNode, node.relNode);
+ elog(DEBUG1, "page %u of relation %u/%u/%u/%u is uninitialized",
+ blkno, node.spcNode, node.dbNode, node.relNode, forkno);
else
- elog(DEBUG1, "page %u of relation %u/%u/%u does not exist",
- blkno, node.spcNode, node.dbNode, node.relNode);
+ elog(DEBUG1, "page %u of relation %u/%u/%u/%u does not exist",
+ blkno, node.spcNode, node.dbNode, node.relNode, forkno);
if (invalid_page_tab == NULL)
{
@@ -87,6 +89,7 @@ log_invalid_page(RelFileNode node, BlockNumber blkno, bool present)
/* we currently assume xl_invalid_page_key contains no padding */
key.node = node;
+ key.forkno = forkno;
key.blkno = blkno;
hentry = (xl_invalid_page *)
hash_search(invalid_page_tab, (void *) &key, HASH_ENTER, &found);
@@ -104,7 +107,7 @@ log_invalid_page(RelFileNode node, BlockNumber blkno, bool present)
/* Forget any invalid pages >= minblkno, because they've been dropped */
static void
-forget_invalid_pages(RelFileNode node, BlockNumber minblkno)
+forget_invalid_pages(RelFileNode node, ForkNumber forkno, BlockNumber minblkno)
{
HASH_SEQ_STATUS status;
xl_invalid_page *hentry;
@@ -117,11 +120,12 @@ forget_invalid_pages(RelFileNode node, BlockNumber minblkno)
while ((hentry = (xl_invalid_page *) hash_seq_search(&status)) != NULL)
{
if (RelFileNodeEquals(hentry->key.node, node) &&
+ hentry->key.forkno == forkno &&
hentry->key.blkno >= minblkno)
{
- elog(DEBUG2, "page %u of relation %u/%u/%u has been dropped",
+ elog(DEBUG2, "page %u of relation %u/%u/%u/%u has been dropped",
hentry->key.blkno, hentry->key.node.spcNode,
- hentry->key.node.dbNode, hentry->key.node.relNode);
+ hentry->key.node.dbNode, hentry->key.node.relNode, forkno);
if (hash_search(invalid_page_tab,
(void *) &hentry->key,
@@ -224,6 +228,18 @@ XLogCheckInvalidPages(void)
Buffer
XLogReadBuffer(RelFileNode rnode, BlockNumber blkno, bool init)
{
+ return XLogReadBufferWithFork(rnode, MAIN_FORKNUM, blkno, init);
+}
+
+/*
+ * XLogReadBufferWithFork
+ * Like XLogReadBuffer, but for reading other relation forks than
+ * the main one.
+ */
+Buffer
+XLogReadBufferWithFork(RelFileNode rnode, ForkNumber forknum,
+ BlockNumber blkno, bool init)
+{
BlockNumber lastblock;
Buffer buffer;
SMgrRelation smgr;
@@ -241,21 +257,21 @@ XLogReadBuffer(RelFileNode rnode, BlockNumber blkno, bool init)
* filesystem loses an inode during a crash. Better to write the data
* until we are actually told to delete the file.)
*/
- smgrcreate(smgr, false, true);
+ smgrcreate(smgr, forknum, false, true);
- lastblock = smgrnblocks(smgr);
+ lastblock = smgrnblocks(smgr, forknum);
if (blkno < lastblock)
{
/* page exists in file */
- buffer = ReadBufferWithoutRelcache(rnode, false, blkno, init);
+ buffer = ReadBufferWithoutRelcache(rnode, false, forknum, blkno, init);
}
else
{
/* hm, page doesn't exist in file */
if (!init)
{
- log_invalid_page(rnode, blkno, false);
+ log_invalid_page(rnode, forknum, blkno, false);
return InvalidBuffer;
}
/* OK to extend the file */
@@ -266,7 +282,8 @@ XLogReadBuffer(RelFileNode rnode, BlockNumber blkno, bool init)
{
if (buffer != InvalidBuffer)
ReleaseBuffer(buffer);
- buffer = ReadBufferWithoutRelcache(rnode, false, P_NEW, false);
+ buffer = ReadBufferWithoutRelcache(rnode, false, forknum,
+ P_NEW, false);
lastblock++;
}
Assert(BufferGetBlockNumber(buffer) == blkno);
@@ -282,7 +299,7 @@ XLogReadBuffer(RelFileNode rnode, BlockNumber blkno, bool init)
if (PageIsNew(page))
{
UnlockReleaseBuffer(buffer);
- log_invalid_page(rnode, blkno, true);
+ log_invalid_page(rnode, forknum, blkno, true);
return InvalidBuffer;
}
}
@@ -363,12 +380,9 @@ FreeFakeRelcacheEntry(Relation fakerel)
* any open "invalid-page" records for the relation.
*/
void
-XLogDropRelation(RelFileNode rnode)
+XLogDropRelation(RelFileNode rnode, ForkNumber forknum)
{
- /* Tell smgr to forget about this relation as well */
- smgrclosenode(rnode);
-
- forget_invalid_pages(rnode, 0);
+ forget_invalid_pages(rnode, forknum, 0);
}
/*
@@ -397,7 +411,8 @@ XLogDropDatabase(Oid dbid)
* We need to clean up any open "invalid-page" records for the dropped pages.
*/
void
-XLogTruncateRelation(RelFileNode rnode, BlockNumber nblocks)
+XLogTruncateRelation(RelFileNode rnode, ForkNumber forkNum,
+ BlockNumber nblocks)
{
- forget_invalid_pages(rnode, nblocks);
+ forget_invalid_pages(rnode, forkNum, nblocks);
}