]> granicus.if.org Git - postgresql/commitdiff
Fix handling of pg_stat_statements.stat temporary file
authorMagnus Hagander <magnus@hagander.net>
Sun, 27 May 2012 08:54:31 +0000 (10:54 +0200)
committerMagnus Hagander <magnus@hagander.net>
Sun, 27 May 2012 08:54:31 +0000 (10:54 +0200)
Write the file to a temporary name and then rename() it into the
permanent name, to ensure it can't end up half-written and corrupt
in case of a crash during shutdown.

Unlink the file after it has been read so it's removed from the data
directory and not included in base backups going to replication slaves.

contrib/pg_stat_statements/pg_stat_statements.c

index 8347c8e9887a8baea8113d6697fa961a471ed960..06869fa344e8a5b23c613574f26787dd2e424fb8 100644 (file)
@@ -511,6 +511,13 @@ pgss_shmem_startup(void)
 
        pfree(buffer);
        FreeFile(file);
+
+       /*
+        * Remove the file so it's not included in backups/replication
+        * slaves, etc. A new file will be written on next shutdown.
+        */
+       unlink(PGSS_DUMP_FILE);
+
        return;
 
 error:
@@ -552,7 +559,7 @@ pgss_shmem_shutdown(int code, Datum arg)
        if (!pgss_save)
                return;
 
-       file = AllocateFile(PGSS_DUMP_FILE, PG_BINARY_W);
+       file = AllocateFile(PGSS_DUMP_FILE ".tmp", PG_BINARY_W);
        if (file == NULL)
                goto error;
 
@@ -578,16 +585,25 @@ pgss_shmem_shutdown(int code, Datum arg)
                goto error;
        }
 
+       /*
+        * Rename file into place, so we atomically replace the old one.
+        */
+       if (rename(PGSS_DUMP_FILE ".tmp", PGSS_DUMP_FILE) != 0)
+               ereport(LOG,
+                               (errcode_for_file_access(),
+                                errmsg("could not rename pg_stat_statement file \"%s\": %m",
+                                               PGSS_DUMP_FILE ".tmp")));
+
        return;
 
 error:
        ereport(LOG,
                        (errcode_for_file_access(),
                         errmsg("could not write pg_stat_statement file \"%s\": %m",
-                                       PGSS_DUMP_FILE)));
+                                       PGSS_DUMP_FILE  ".tmp")));
        if (file)
                FreeFile(file);
-       unlink(PGSS_DUMP_FILE);
+       unlink(PGSS_DUMP_FILE ".tmp");
 }
 
 /*