diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index a9ef1b3d73..e8d4e37fe3 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -1456,7 +1456,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 @@ -1549,13 +1548,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 8e6aef332c..1da1f13ef3 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -5516,7 +5516,6 @@ xact_redo_commit(xl_xact_parsed_commit *parsed, RepOriginId origin_id) { TransactionId max_xid; - int i; TimestampTz commit_time; Assert(TransactionIdIsValid(xid)); @@ -5635,16 +5634,8 @@ xact_redo_commit(xl_xact_parsed_commit *parsed, */ XLogFlush(lsn); - for (i = 0; i < parsed->nrels; i++) - { - SMgrRelation srel = smgropen(parsed->xnodes[i], InvalidBackendId); - ForkNumber fork; - - for (fork = 0; fork <= MAX_FORKNUM; fork++) - XLogDropRelation(parsed->xnodes[i], fork); - smgrdounlink(srel, true); - smgrclose(srel); - } + /* Make sure files supposed to be dropped are dropped */ + DropRelationFiles(parsed->xnodes, parsed->nrels, true); } /* @@ -5683,7 +5674,6 @@ xact_redo_commit(xl_xact_parsed_commit *parsed, static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid) { - int i; TransactionId max_xid; Assert(TransactionIdIsValid(xid)); @@ -5748,16 +5738,7 @@ xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid) } /* Make sure files supposed to be dropped are dropped */ - for (i = 0; i < parsed->nrels; i++) - { - SMgrRelation srel = smgropen(parsed->xnodes[i], InvalidBackendId); - ForkNumber fork; - - for (fork = 0; fork <= MAX_FORKNUM; fork++) - XLogDropRelation(parsed->xnodes[i], fork); - smgrdounlink(srel, true); - smgrclose(srel); - } + DropRelationFiles(parsed->xnodes, parsed->nrels, true); } void diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index 2ec103e604..f4374d077b 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -26,6 +26,7 @@ #include #include "miscadmin.h" +#include "access/xlogutils.h" #include "access/xlog.h" #include "pgstat.h" #include "portability/instr_time.h" @@ -1703,6 +1704,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_resize() -- Resize the fork's open segments array diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h index 558e4d8518..c843bbc969 100644 --- a/src/include/storage/smgr.h +++ b/src/include/storage/smgr.h @@ -143,5 +143,6 @@ 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); #endif /* SMGR_H */