Commit f9b50b7c authored by Alvaro Herrera's avatar Alvaro Herrera

Fix removal of files in pgstats directories

Instead of deleting all files in stats_temp_directory and the permanent
directory on a crash, only remove those files that match the pattern of
files we actually write in them, to avoid possibly clobbering existing
unrelated contents of the temporary directory.  Per complaint from Jeff
Janes, and subsequent discussion, starting at message
CAMkU=1z9+7RsDODnT4=cDFBRBp8wYQbd_qsLcMtKEf-oFwuOdQ@mail.gmail.com

Also, fix a bug in the same routine to avoid removing files from the
permanent directory twice (instead of once from that directory and then
from the temporary directory), also per report from Jeff Janes, in
message
CAMkU=1wbk947=-pAosDMX5VC+sQw9W4ttq6RM9rXu=MjNeEQKA@mail.gmail.com
parent 3619a20d
...@@ -563,15 +563,37 @@ pgstat_reset_remove_files(const char *directory) ...@@ -563,15 +563,37 @@ pgstat_reset_remove_files(const char *directory)
struct dirent *entry; struct dirent *entry;
char fname[MAXPGPATH]; char fname[MAXPGPATH];
dir = AllocateDir(pgstat_stat_directory); dir = AllocateDir(directory);
while ((entry = ReadDir(dir, pgstat_stat_directory)) != NULL) while ((entry = ReadDir(dir, directory)) != NULL)
{ {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) int nitems;
Oid tmp_oid;
char tmp_type[8];
char tmp_rest[2];
if (strncmp(entry->d_name, ".", 2) == 0 ||
strncmp(entry->d_name, "..", 3) == 0)
continue;
/*
* Skip directory entries that don't match the file names we write.
* See get_dbstat_filename for the database-specific pattern.
*/
nitems = sscanf(entry->d_name, "db_%u.%5s%1s",
&tmp_oid, tmp_type, tmp_rest);
if (nitems != 2)
{
nitems = sscanf(entry->d_name, "global.%5s%1s",
tmp_type, tmp_rest);
if (nitems != 1)
continue; continue;
}
/* XXX should we try to ignore files other than the ones we write? */ if (strncmp(tmp_type, "tmp", 4) != 0 &&
strncmp(tmp_type, "stat", 5) != 0)
continue;
snprintf(fname, MAXPGPATH, "%s/%s", pgstat_stat_directory, snprintf(fname, MAXPGPATH, "%s/%s", directory,
entry->d_name); entry->d_name);
unlink(fname); unlink(fname);
} }
...@@ -3631,6 +3653,7 @@ get_dbstat_filename(bool permanent, bool tempname, Oid databaseid, ...@@ -3631,6 +3653,7 @@ get_dbstat_filename(bool permanent, bool tempname, Oid databaseid,
{ {
int printed; int printed;
/* NB -- pgstat_reset_remove_files knows about the pattern this uses */
printed = snprintf(filename, len, "%s/db_%u.%s", printed = snprintf(filename, len, "%s/db_%u.%s",
permanent ? PGSTAT_STAT_PERMANENT_DIRECTORY : permanent ? PGSTAT_STAT_PERMANENT_DIRECTORY :
pgstat_stat_directory, pgstat_stat_directory,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment