Skip to content

Commit ab9a14e

Browse files
committed
Fix WAL file replacement during cascading replication on Windows.
When the startup process restores a WAL file from the archive, it deletes any old file with the same name and renames the new file in its place. On Windows, however, when a file is deleted, it still lingers as long as a process holds a file handle open on it. With cascading replication, a walsender process can hold the old file open, so the rename() in the startup process would fail. To fix that, rename the old file to a temporary name, to make the original file name available for reuse, before deleting the old file.
1 parent 2e0cc1f commit ab9a14e

File tree

1 file changed

+27
-1
lines changed
  • src/backend/access/transam

1 file changed

+27
-1
lines changed

src/backend/access/transam/xlog.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2787,7 +2787,33 @@ XLogFileRead(XLogSegNo segno, int emode, TimeLineID tli,
27872787
XLogFilePath(xlogfpath, tli, segno);
27882788
if (stat(xlogfpath, &statbuf) == 0)
27892789
{
2790-
if (unlink(xlogfpath) != 0)
2790+
char oldpath[MAXPGPATH];
2791+
#ifdef WIN32
2792+
static unsigned int deletedcounter = 1;
2793+
/*
2794+
* On Windows, if another process (e.g a walsender process) holds
2795+
* the file open in FILE_SHARE_DELETE mode, unlink will succeed,
2796+
* but the file will still show up in directory listing until the
2797+
* last handle is closed, and we cannot rename the new file in its
2798+
* place until that. To avoid that problem, rename the old file to
2799+
* a temporary name first. Use a counter to create a unique
2800+
* filename, because the same file might be restored from the
2801+
* archive multiple times, and a walsender could still be holding
2802+
* onto an old deleted version of it.
2803+
*/
2804+
snprintf(oldpath, MAXPGPATH, "%s.deleted%u",
2805+
xlogfpath, deletedcounter++);
2806+
if (rename(xlogfpath, oldpath) != 0)
2807+
{
2808+
ereport(ERROR,
2809+
(errcode_for_file_access(),
2810+
errmsg("could not rename file \"%s\" to \"%s\": %m",
2811+
xlogfpath, oldpath)));
2812+
}
2813+
#else
2814+
strncpy(oldpath, xlogfpath, MAXPGPATH);
2815+
#endif
2816+
if (unlink(oldpath) != 0)
27912817
ereport(FATAL,
27922818
(errcode_for_file_access(),
27932819
errmsg("could not remove file \"%s\": %m",

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy