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.
REL9_1_STABLE
Magnus Hagander 14 years ago
parent 6c1bf45ea5
commit 2791f2180d
  1. 22
      contrib/pg_stat_statements/pg_stat_statements.c

@ -427,6 +427,13 @@ pgss_shmem_startup(void)
pfree(buffer); pfree(buffer);
FreeFile(file); 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; return;
error: error:
@ -468,7 +475,7 @@ pgss_shmem_shutdown(int code, Datum arg)
if (!pgss_save) if (!pgss_save)
return; return;
file = AllocateFile(PGSS_DUMP_FILE, PG_BINARY_W); file = AllocateFile(PGSS_DUMP_FILE ".tmp", PG_BINARY_W);
if (file == NULL) if (file == NULL)
goto error; goto error;
@ -494,16 +501,25 @@ pgss_shmem_shutdown(int code, Datum arg)
goto error; 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; return;
error: error:
ereport(LOG, ereport(LOG,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not write pg_stat_statement file \"%s\": %m", errmsg("could not write pg_stat_statement file \"%s\": %m",
PGSS_DUMP_FILE))); PGSS_DUMP_FILE ".tmp")));
if (file) if (file)
FreeFile(file); FreeFile(file);
unlink(PGSS_DUMP_FILE); unlink(PGSS_DUMP_FILE ".tmp");
} }
/* /*

Loading…
Cancel
Save