aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Hagander <magnus@hagander.net>2012-05-27 10:54:31 +0200
committerMagnus Hagander <magnus@hagander.net>2012-05-27 10:54:31 +0200
commit2b97db61dd0bffb0843eb2ea9be054d925e88ef1 (patch)
treee0941e73fb33295339db2ba6d74d328d22a27033
parent532fe28dade9291b7a7f7de3920a4d997bbd86a1 (diff)
downloadpostgresql-2b97db61dd0bffb0843eb2ea9be054d925e88ef1.tar.gz
postgresql-2b97db61dd0bffb0843eb2ea9be054d925e88ef1.zip
Fix handling of pg_stat_statements.stat temporary file
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.
-rw-r--r--contrib/pg_stat_statements/pg_stat_statements.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 8347c8e9887..06869fa344e 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -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");
}
/*