]> granicus.if.org Git - postgresql/commitdiff
Arrange to fsync the contents of lockfiles (both postmaster.pid and the
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 16 Aug 2010 17:32:46 +0000 (17:32 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 16 Aug 2010 17:32:46 +0000 (17:32 +0000)
socket lockfile) when writing them.  The lack of an fsync here may well
explain two different reports we've seen of corrupted lockfile contents,
which doesn't particularly bother the running server but can prevent a
new server from starting if the old one crashes.  Per suggestion from
Alvaro.

Back-patch to all supported versions.

src/backend/utils/init/miscinit.c

index e6b6676706fdb596a07a97e2b3eb49fc9d039224..973f5840671f75e557937ff3e9429992defac668 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.184 2010/04/20 23:48:47 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.185 2010/08/16 17:32:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -818,6 +818,9 @@ CreateLockFile(const char *filename, bool amPostmaster,
                 * admin) but has left orphan backends behind.  Check for this by
                 * looking to see if there is an associated shmem segment that is
                 * still in use.
+                *
+                * Note: because postmaster.pid is written in two steps, we might not
+                * find the shmem ID values in it; we can't treat that as an error.
                 */
                if (isDDLock)
                {
@@ -881,7 +884,18 @@ CreateLockFile(const char *filename, bool amPostmaster,
                                (errcode_for_file_access(),
                                 errmsg("could not write lock file \"%s\": %m", filename)));
        }
-       if (close(fd))
+       if (pg_fsync(fd) != 0)
+       {
+               int                     save_errno = errno;
+
+               close(fd);
+               unlink(filename);
+               errno = save_errno;
+               ereport(FATAL,
+                               (errcode_for_file_access(),
+                                errmsg("could not write lock file \"%s\": %m", filename)));
+       }
+       if (close(fd) != 0)
        {
                int                     save_errno = errno;
 
@@ -1042,7 +1056,14 @@ RecordSharedMemoryInLockFile(unsigned long id1, unsigned long id2)
                close(fd);
                return;
        }
-       if (close(fd))
+       if (pg_fsync(fd) != 0)
+       {
+               ereport(LOG,
+                               (errcode_for_file_access(),
+                                errmsg("could not write to file \"%s\": %m",
+                                               DIRECTORY_LOCK_FILE)));
+       }
+       if (close(fd) != 0)
        {
                ereport(LOG,
                                (errcode_for_file_access(),