diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index 6db46c0..c01b170 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -1356,12 +1356,7 @@ FinishPreparedTransaction(const char *gid, bool isCommit) for (i = 0; i < ndelrels; i++) { SMgrRelation srel = smgropen(delrels[i], InvalidBackendId); - ForkNumber fork; - - for (fork = 0; fork <= MAX_FORKNUM; fork++) - { - smgrdounlink(srel, fork, false); - } + smgrdounlink(srel, AllForks, false); smgrclose(srel); } diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 5ae46de..a117660 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -4633,13 +4633,8 @@ xact_redo_commit_internal(TransactionId xid, XLogRecPtr lsn, for (i = 0; i < nrels; i++) { SMgrRelation srel = smgropen(xnodes[i], InvalidBackendId); - ForkNumber fork; - - for (fork = 0; fork <= MAX_FORKNUM; fork++) - { - XLogDropRelation(xnodes[i], fork); - smgrdounlink(srel, fork, true); - } + XLogDropRelation(xnodes[i], AllForks); + smgrdounlink(srel, AllForks, true); smgrclose(srel); } @@ -4773,13 +4768,8 @@ xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid) for (i = 0; i < xlrec->nrels; i++) { SMgrRelation srel = smgropen(xlrec->xnodes[i], InvalidBackendId); - ForkNumber fork; - - for (fork = 0; fork <= MAX_FORKNUM; fork++) - { - XLogDropRelation(xlrec->xnodes[i], fork); - smgrdounlink(srel, fork, true); - } + XLogDropRelation(xlrec->xnodes[i], AllForks); + smgrdounlink(srel, AllForks, true); smgrclose(srel); } } diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c index f286cdf..2578585 100644 --- a/src/backend/access/transam/xlogutils.c +++ b/src/backend/access/transam/xlogutils.c @@ -148,7 +148,7 @@ forget_invalid_pages(RelFileNode node, ForkNumber forkno, BlockNumber minblkno) while ((hentry = (xl_invalid_page *) hash_seq_search(&status)) != NULL) { if (RelFileNodeEquals(hentry->key.node, node) && - hentry->key.forkno == forkno && + (hentry->key.forkno == forkno || forkno == AllForks) && hentry->key.blkno >= minblkno) { if (log_min_messages <= DEBUG2 || client_min_messages <= DEBUG2) diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c index a017101..b871604 100644 --- a/src/backend/catalog/storage.c +++ b/src/backend/catalog/storage.c @@ -356,13 +356,9 @@ smgrDoPendingDeletes(bool isCommit) if (pending->atCommit == isCommit) { SMgrRelation srel; - int i; srel = smgropen(pending->relnode, pending->backend); - for (i = 0; i <= MAX_FORKNUM; i++) - { - smgrdounlink(srel, i, false); - } + smgrdounlink(srel, AllForks, false); smgrclose(srel); } /* must explicitly free the list entry */ diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index a1b588b..124983c 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -2061,7 +2061,8 @@ DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber forkNum, LockBufHdr(bufHdr); if (RelFileNodeEquals(bufHdr->tag.rnode, rnode.node) && - bufHdr->tag.forkNum == forkNum && + (bufHdr->tag.forkNum == forkNum || + forkNum == AllForks) && bufHdr->tag.blockNum >= firstDelBlock) InvalidateBuffer(bufHdr); /* releases spinlock */ else diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index 5f87543..c875606 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -343,9 +343,16 @@ smgrdounlink(SMgrRelation reln, ForkNumber forknum, bool isRedo) { RelFileNodeBackend rnode = reln->smgr_rnode; int which = reln->smgr_which; + int i; /* Close the fork */ - (*(smgrsw[which].smgr_close)) (reln, forknum); + if (forknum == AllForks) + { + for (i = 0; i <= MAX_FORKNUM; i++) + (*(smgrsw[which].smgr_close)) (reln, i); + } + else + (*(smgrsw[which].smgr_close)) (reln, forknum); /* * Get rid of any remaining buffers for the relation. bufmgr will just @@ -377,7 +384,13 @@ smgrdounlink(SMgrRelation reln, ForkNumber forknum, bool isRedo) * ERROR, because we've already decided to commit or abort the current * xact. */ - (*(smgrsw[which].smgr_unlink)) (rnode, forknum, isRedo); + if (forknum == AllForks) + { + for (i = 0; i <= MAX_FORKNUM; i++) + (*(smgrsw[which].smgr_unlink)) (rnode, i, isRedo); + } + else + (*(smgrsw[which].smgr_unlink)) (rnode, forknum, isRedo); } /* diff --git a/src/include/storage/relfilenode.h b/src/include/storage/relfilenode.h index 60c3829..451139c 100644 --- a/src/include/storage/relfilenode.h +++ b/src/include/storage/relfilenode.h @@ -20,10 +20,12 @@ * The physical storage of a relation consists of one or more forks. The * main fork is always created, but in addition to that there can be * additional forks for storing various metadata. ForkNumber is used when - * we need to refer to a specific fork in a relation. + * we need to refer to a specific fork in a relation, or AllForks + * can be used in places to refer to all forks of a relation. */ typedef enum ForkNumber { + AllForks = -2, InvalidForkNumber = -1, MAIN_FORKNUM = 0, FSM_FORKNUM,