diff options
Diffstat (limited to 'src/backend/access/transam/xlogutils.c')
-rw-r--r-- | src/backend/access/transam/xlogutils.c | 59 |
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); } |