* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.258.2.6 2009/09/10 09:43:32 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.258.2.7 2009/09/13 18:32:34 heikki Exp $
*
*-------------------------------------------------------------------------
*/
*use_existent, &max_advance,
use_lock))
{
- /* No need for any more future segments... */
+ /*
+ * No need for any more future segments, or InstallXLogFileSegment()
+ * failed to rename the file into place. If the rename failed, opening
+ * the file below will fail.
+ */
unlink(tmppath);
}
* place. This should be TRUE except during bootstrap log creation. The
* caller must *not* hold the lock at call.
*
- * Returns TRUE if file installed, FALSE if not installed because of
- * exceeding max_advance limit. On Windows, we also return FALSE if we
- * can't rename the file into place because someone's got it open.
- * (Any other kind of failure causes ereport().)
+ * Returns TRUE if the file was installed successfully. FALSE indicates that
+ * max_advance limit was exceeded, or an error occurred while renaming the
+ * file into place.
*/
static bool
InstallXLogFileSegment(uint32 *log, uint32 *seg, char *tmppath,
*/
#if HAVE_WORKING_LINK
if (link(tmppath, path) < 0)
- ereport(ERROR,
+ {
+ if (use_lock)
+ LWLockRelease(ControlFileLock);
+ ereport(LOG,
(errcode_for_file_access(),
errmsg("could not link file \"%s\" to \"%s\" (initialization of log file %u, segment %u): %m",
tmppath, path, *log, *seg)));
+ return false;
+ }
unlink(tmppath);
#else
if (rename(tmppath, path) < 0)
{
-#ifdef WIN32
-#if !defined(__CYGWIN__)
- if (GetLastError() == ERROR_ACCESS_DENIED)
-#else
- if (errno == EACCES)
-#endif
- {
- if (use_lock)
- LWLockRelease(ControlFileLock);
- return false;
- }
-#endif /* WIN32 */
-
- ereport(ERROR,
+ if (use_lock)
+ LWLockRelease(ControlFileLock);
+ ereport(LOG,
(errcode_for_file_access(),
errmsg("could not rename file \"%s\" to \"%s\" (initialization of log file %u, segment %u): %m",
tmppath, path, *log, *seg)));
+ return false;
}
#endif
*/
snprintf(newpath, MAXPGPATH, "%s.deleted", path);
if (rename(path, newpath) != 0)
- ereport(ERROR,
+ {
+ ereport(LOG,
(errcode_for_file_access(),
errmsg("could not rename old transaction log file \"%s\"",
path)));
+ continue;
+ }
rc = unlink(newpath);
#else
rc = unlink(path);
#endif
if (rc != 0)
- ereport(ERROR,
+ {
+ ereport(LOG,
(errcode_for_file_access(),
errmsg("could not remove old transaction log file \"%s\": %m",
path)));
+ continue;
+ }
(*nsegsremoved)++;
}
* Win32 (NT, Win2k, XP). replace() doesn't work on Win95/98/Me.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/port/dirmod.c,v 1.44.2.3 2008/04/12 00:00:08 tgl Exp $
+ * $PostgreSQL: pgsql/src/port/dirmod.c,v 1.44.2.4 2009/09/13 18:32:35 heikki Exp $
*
*-------------------------------------------------------------------------
*/
int loops = 0;
/*
- * We need to loop because even though PostgreSQL uses flags that
- * allow rename while the file is open, other applications might have
- * the file open without those flags. However, we won't wait
- * indefinitely for someone else to close the file.
+ * We need to loop because even though PostgreSQL uses flags that allow
+ * rename while the file is open, other applications might have the file
+ * open without those flags. However, we won't wait indefinitely for
+ * someone else to close the file, as the caller might be holding locks
+ * and blocking other backends.
*/
#if defined(WIN32) && !defined(__CYGWIN__)
while (!MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING))
#endif
{
#if defined(WIN32) && !defined(__CYGWIN__)
- if (GetLastError() != ERROR_ACCESS_DENIED)
+ DWORD err = GetLastError();
+
+ _dosmaperr(err);
+
+ /*
+ * Modern NT-based Windows versions return ERROR_SHARING_VIOLATION
+ * if another process has the file open without FILE_SHARE_DELETE.
+ * ERROR_LOCK_VIOLATION has also been seen with some anti-virus
+ * software. This used to check for just ERROR_ACCESS_DENIED, so
+ * presumably you can get that too with some OS versions. We don't
+ * expect real permission errors where we currently use rename().
+ */
+ if (err != ERROR_ACCESS_DENIED &&
+ err != ERROR_SHARING_VIOLATION &&
+ err != ERROR_LOCK_VIOLATION)
+ return -1;
#else
if (errno != EACCES)
-#endif
- /* set errno? */
return -1;
- if (++loops > 300) /* time out after 30 sec */
+#endif
+
+ if (++loops > 100) /* time out after 10 sec */
return -1;
pg_usleep(100000); /* us */
}
int loops = 0;
/*
- * We need to loop because even though PostgreSQL uses flags that
- * allow unlink while the file is open, other applications might have
- * the file open without those flags. However, we won't wait
- * indefinitely for someone else to close the file.
+ * We need to loop because even though PostgreSQL uses flags that allow
+ * unlink while the file is open, other applications might have the file
+ * open without those flags. However, we won't wait indefinitely for
+ * someone else to close the file, as the caller might be holding locks
+ * and blocking other backends.
*/
while (unlink(path))
{
if (errno != EACCES)
- /* set errno? */
return -1;
- if (++loops > 300) /* time out after 30 sec */
+ if (++loops > 100) /* time out after 10 sec */
return -1;
pg_usleep(100000); /* us */
}