diff options
Diffstat (limited to 'src/backend/storage/smgr/md.c')
-rw-r--r-- | src/backend/storage/smgr/md.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index 43edaf5d873..a0fc60b32a3 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -319,6 +319,7 @@ mdunlinkfork(RelFileNodeBackend rnode, ForkNumber forkNum, bool isRedo) { char *path; int ret; + BlockNumber segno = 0; path = relpath(rnode, forkNum); @@ -353,8 +354,22 @@ mdunlinkfork(RelFileNodeBackend rnode, ForkNumber forkNum, bool isRedo) /* Prevent other backends' fds from holding on to the disk space */ ret = do_truncate(path); - /* Register request to unlink first segment later */ - register_unlink_segment(rnode, forkNum, 0 /* first seg */ ); + /* + * Except during a binary upgrade, register request to unlink first + * segment later, rather than now. + * + * If we're performing a binary upgrade, the dangers described in the + * header comments for mdunlink() do not exist, since after a crash + * or even a simple ERROR, the upgrade fails and the whole new cluster + * must be recreated from scratch. And, on the other hand, it is + * important to remove the files from disk immediately, because we + * may be about to reuse the same relfilenode. + */ + if (!IsBinaryUpgrade) + { + register_unlink_segment(rnode, forkNum, 0 /* first seg */ ); + ++segno; + } } /* @@ -363,15 +378,17 @@ mdunlinkfork(RelFileNodeBackend rnode, ForkNumber forkNum, bool isRedo) if (ret >= 0) { char *segpath = (char *) palloc(strlen(path) + 12); - BlockNumber segno; /* * Note that because we loop until getting ENOENT, we will correctly * remove all inactive segments as well as active ones. */ - for (segno = 1;; segno++) + for (;; segno++) { - sprintf(segpath, "%s.%u", path, segno); + if (segno == 0) + strcpy(segpath, path); + else + sprintf(segpath, "%s.%u", path, segno); if (!RelFileNodeBackendIsTemp(rnode)) { |