]> 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:58:14 +0000 (10:58 +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 0236b87498fa27a4c445046469f89b7615e75632..590512fdcdb47702d68f197e2abcbfdc0970c4b7 100644 (file)
@@ -427,6 +427,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:
@@ -468,7 +475,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;
 
@@ -494,16 +501,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");
 }
 
 /*