diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index d78ed62ea773d80639356a8e5a85c052a74c7a19..c04baf34039f6c81d480e1d9291a8aae8303aba8 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -1362,7 +1362,6 @@ FinishPreparedTransaction(const char *gid, bool isCommit) RelFileNode *delrels; int ndelrels; SharedInvalidationMessage *invalmsgs; - int i; /* * Validate the GID, and lock the GXACT to ensure that two backends do not @@ -1452,13 +1451,9 @@ FinishPreparedTransaction(const char *gid, bool isCommit) delrels = abortrels; ndelrels = hdr->nabortrels; } - for (i = 0; i < ndelrels; i++) - { - SMgrRelation srel = smgropen(delrels[i], InvalidBackendId); - smgrdounlink(srel, false); - smgrclose(srel); - } + /* Make sure files supposed to be dropped are dropped */ + DropRelationFiles(delrels, ndelrels, false); /* * Handle cache invalidation messages. diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 59cb3aab9f787fb0f15789f389191b2063b90422..fc6000539e75ccaea3c05475eceafee959eacba2 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -4710,7 +4710,6 @@ xact_redo_commit_internal(TransactionId xid, XLogRecPtr lsn, uint32 xinfo) { TransactionId max_xid; - int i; max_xid = TransactionIdLatest(xid, nsubxacts, sub_xids); @@ -4805,16 +4804,8 @@ xact_redo_commit_internal(TransactionId xid, XLogRecPtr lsn, */ XLogFlush(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, true); - smgrclose(srel); - } + /* Make sure files supposed to be dropped are dropped */ + DropRelationFiles(xnodes, nrels, true); } /* @@ -4886,7 +4877,6 @@ xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid) { TransactionId *sub_xids; TransactionId max_xid; - int i; sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]); max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids); @@ -4945,16 +4935,7 @@ xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid) } /* Make sure files supposed to be dropped are dropped */ - 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, true); - smgrclose(srel); - } + DropRelationFiles(xlrec->xnodes, xlrec->nrels, true); } void diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index 6e7430bac4b8f11fa8755280d7fb6fc684461237..73e11e9a78a73b8dcaa7d4ea984d774045ee3434 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -26,6 +26,7 @@ #include <sys/file.h> #include "miscadmin.h" +#include "access/xlogutils.h" #include "access/xlog.h" #include "catalog/catalog.h" #include "portability/instr_time.h" @@ -1625,6 +1626,43 @@ ForgetDatabaseFsyncRequests(Oid dbid) } } +/* + * DropRelationFiles -- drop files of all given relations + */ +void +DropRelationFiles(RelFileNode *delrels, int ndelrels, bool isRedo) +{ + SMgrRelation *srels; + int i; + + srels = palloc(sizeof(SMgrRelation) * ndelrels); + for (i = 0; i < ndelrels; i++) + { + SMgrRelation srel = smgropen(delrels[i], InvalidBackendId); + + if (isRedo) + { + ForkNumber fork; + + for (fork = 0; fork <= MAX_FORKNUM; fork++) + XLogDropRelation(delrels[i], fork); + } + srels[i] = srel; + } + + smgrdounlinkall(srels, ndelrels, isRedo); + + /* + * Call smgrclose() in reverse order as when smgropen() is called. + * This trick enables remove_from_unowned_list() in smgrclose() + * to search the SMgrRelation from the unowned list, + * with O(1) performance. + */ + for (i = ndelrels - 1; i >= 0; i--) + smgrclose(srels[i]); + pfree(srels); +} + /* * _fdvec_alloc() -- Make a MdfdVec object. diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h index ba7c909451d9c1b46c6d3f97a7e7b536f758c721..7b27cf5331671f46330b066b0526f57ddf053386 100644 --- a/src/include/storage/smgr.h +++ b/src/include/storage/smgr.h @@ -135,6 +135,7 @@ extern void RememberFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno); extern void ForgetRelationFsyncRequests(RelFileNode rnode, ForkNumber forknum); extern void ForgetDatabaseFsyncRequests(Oid dbid); +extern void DropRelationFiles(RelFileNode *delrels, int ndelrels, bool isRedo); /* smgrtype.c */ extern Datum smgrout(PG_FUNCTION_ARGS);