aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/transam/xlog.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 022c1b20acd..56e6b8269e4 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.345.2.3 2009/08/27 07:18:04 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.345.2.4 2009/09/10 09:42:29 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -3040,6 +3040,9 @@ RemoveOldXlogFiles(uint32 log, uint32 seg, XLogRecPtr endptr)
struct dirent *xlde;
char lastoff[MAXFNAMELEN];
char path[MAXPGPATH];
+#ifdef WIN32
+ char newpath[MAXPGPATH];
+#endif
struct stat statbuf;
/*
@@ -3103,10 +3106,41 @@ RemoveOldXlogFiles(uint32 log, uint32 seg, XLogRecPtr endptr)
else
{
/* No need for any more future segments... */
+ int rc;
+
ereport(DEBUG2,
(errmsg("removing transaction log file \"%s\"",
xlde->d_name)));
- unlink(path);
+
+#ifdef WIN32
+ /*
+ * On Windows, if another process (e.g another backend)
+ * holds the file open in FILE_SHARE_DELETE mode, unlink
+ * will succeed, but the file will still show up in
+ * directory listing until the last handle is closed.
+ * To avoid confusing the lingering deleted file for a
+ * live WAL file that needs to be archived, rename it
+ * before deleting it.
+ *
+ * If another process holds the file open without
+ * FILE_SHARE_DELETE flag, rename will fail. We'll try
+ * again at the next checkpoint.
+ */
+ snprintf(newpath, MAXPGPATH, "%s.deleted", path);
+ if (rename(path, newpath) != 0)
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not rename old transaction log file \"%s\"",
+ path)));
+ rc = unlink(newpath);
+#else
+ rc = unlink(path);
+#endif
+ if (rc != 0)
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not remove old transaction log file \"%s\": %m",
+ path)));
CheckpointStats.ckpt_segs_removed++;
}