diff options
Diffstat (limited to 'src/backend/storage/smgr/smgr.c')
-rw-r--r-- | src/backend/storage/smgr/smgr.c | 65 |
1 files changed, 61 insertions, 4 deletions
diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index 5f87543bb03..60eb81f774f 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -329,7 +329,64 @@ smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo) } /* - * smgrdounlink() -- Immediately unlink a relation. + * smgrdounlink() -- Immediately unlink all forks of a relation. + * + * All forks of the relation are removed from the store. This should + * not be used during transactional operations, since it can't be undone. + * + * If isRedo is true, it is okay for the underlying file(s) to be gone + * already. + * + * This is equivalent to calling smgrdounlinkfork for each fork, but + * it's significantly quicker so should be preferred when possible. + */ +void +smgrdounlink(SMgrRelation reln, bool isRedo) +{ + RelFileNodeBackend rnode = reln->smgr_rnode; + int which = reln->smgr_which; + ForkNumber forknum; + + /* Close the forks at smgr level */ + for (forknum = 0; forknum <= MAX_FORKNUM; forknum++) + (*(smgrsw[which].smgr_close)) (reln, forknum); + + /* + * Get rid of any remaining buffers for the relation. bufmgr will just + * drop them without bothering to write the contents. + */ + DropRelFileNodeAllBuffers(rnode); + + /* + * It'd be nice to tell the stats collector to forget it immediately, too. + * But we can't because we don't know the OID (and in cases involving + * relfilenode swaps, it's not always clear which table OID to forget, + * anyway). + */ + + /* + * Send a shared-inval message to force other backends to close any + * dangling smgr references they may have for this rel. We should do this + * before starting the actual unlinking, in case we fail partway through + * that step. Note that the sinval message will eventually come back to + * this backend, too, and thereby provide a backstop that we closed our + * own smgr rel. + */ + CacheInvalidateSmgr(rnode); + + /* + * Delete the physical file(s). + * + * Note: smgr_unlink must treat deletion failure as a WARNING, not an + * ERROR, because we've already decided to commit or abort the current + * xact. + */ + for (forknum = 0; forknum <= MAX_FORKNUM; forknum++) + (*(smgrsw[which].smgr_unlink)) (rnode, forknum, isRedo); +} + +/* + * smgrdounlinkfork() -- Immediately unlink one fork of a relation. * * The specified fork of the relation is removed from the store. This * should not be used during transactional operations, since it can't be @@ -339,16 +396,16 @@ smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo) * already. */ void -smgrdounlink(SMgrRelation reln, ForkNumber forknum, bool isRedo) +smgrdounlinkfork(SMgrRelation reln, ForkNumber forknum, bool isRedo) { RelFileNodeBackend rnode = reln->smgr_rnode; int which = reln->smgr_which; - /* Close the fork */ + /* Close the fork at smgr level */ (*(smgrsw[which].smgr_close)) (reln, forknum); /* - * Get rid of any remaining buffers for the relation. bufmgr will just + * Get rid of any remaining buffers for the fork. bufmgr will just * drop them without bothering to write the contents. */ DropRelFileNodeBuffers(rnode, forknum, 0); |