Commit eeb3c2df authored by Tom Lane's avatar Tom Lane

Back off chattiness in RemovePgTempFiles().

In commit 561885db, as part of normalizing RemovePgTempFiles's error
handling, I removed its behavior of silently ignoring ENOENT failures
during directory opens.  Thomas Munro points out that this is a bad idea at
the top level, because we don't create pgsql_tmp directories until needed.
Thus this coding could produce LOG messages in perfectly normal situations,
which isn't what I intended.  Restore the suppression of ENOENT logging,
but only at top level --- it would still be unexpected for a nested temp
directory to disappear between seeing it in the parent directory and
opening it.

Discussion: https://postgr.es/m/CAEepm=2y06SehAkTnd5sU_eVqdv5P-=Srt1y5vYNQk6yVDVaPw@mail.gmail.com
parent 6271fceb
...@@ -321,7 +321,8 @@ static int FreeDesc(AllocateDesc *desc); ...@@ -321,7 +321,8 @@ static int FreeDesc(AllocateDesc *desc);
static void AtProcExit_Files(int code, Datum arg); static void AtProcExit_Files(int code, Datum arg);
static void CleanupTempFiles(bool isProcExit); static void CleanupTempFiles(bool isProcExit);
static void RemovePgTempFilesInDir(const char *tmpdirname, bool unlink_all); static void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok,
bool unlink_all);
static void RemovePgTempRelationFiles(const char *tsdirname); static void RemovePgTempRelationFiles(const char *tsdirname);
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname); static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname);
static bool looks_like_temp_rel_name(const char *name); static bool looks_like_temp_rel_name(const char *name);
...@@ -3010,7 +3011,7 @@ RemovePgTempFiles(void) ...@@ -3010,7 +3011,7 @@ RemovePgTempFiles(void)
* First process temp files in pg_default ($PGDATA/base) * First process temp files in pg_default ($PGDATA/base)
*/ */
snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR); snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
RemovePgTempFilesInDir(temp_path, false); RemovePgTempFilesInDir(temp_path, true, false);
RemovePgTempRelationFiles("base"); RemovePgTempRelationFiles("base");
/* /*
...@@ -3026,7 +3027,7 @@ RemovePgTempFiles(void) ...@@ -3026,7 +3027,7 @@ RemovePgTempFiles(void)
snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s", snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
spc_de->d_name, TABLESPACE_VERSION_DIRECTORY, PG_TEMP_FILES_DIR); spc_de->d_name, TABLESPACE_VERSION_DIRECTORY, PG_TEMP_FILES_DIR);
RemovePgTempFilesInDir(temp_path, false); RemovePgTempFilesInDir(temp_path, true, false);
snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s", snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
spc_de->d_name, TABLESPACE_VERSION_DIRECTORY); spc_de->d_name, TABLESPACE_VERSION_DIRECTORY);
...@@ -3040,19 +3041,27 @@ RemovePgTempFiles(void) ...@@ -3040,19 +3041,27 @@ RemovePgTempFiles(void)
* DataDir as well. * DataDir as well.
*/ */
#ifdef EXEC_BACKEND #ifdef EXEC_BACKEND
RemovePgTempFilesInDir(PG_TEMP_FILES_DIR, false); RemovePgTempFilesInDir(PG_TEMP_FILES_DIR, true, false);
#endif #endif
} }
/* /*
* Process one pgsql_tmp directory for RemovePgTempFiles. At the top level in * Process one pgsql_tmp directory for RemovePgTempFiles.
* each tablespace, this should be called with unlink_all = false, so that *
* If missing_ok is true, it's all right for the named directory to not exist.
* Any other problem results in a LOG message. (missing_ok should be true at
* the top level, since pgsql_tmp directories are not created until needed.)
*
* At the top level, this should be called with unlink_all = false, so that
* only files matching the temporary name prefix will be unlinked. When * only files matching the temporary name prefix will be unlinked. When
* recursing it will be called with unlink_all = true to unlink everything * recursing it will be called with unlink_all = true to unlink everything
* under a top-level temporary directory. * under a top-level temporary directory.
*
* (These two flags could be replaced by one, but it seems clearer to keep
* them separate.)
*/ */
static void static void
RemovePgTempFilesInDir(const char *tmpdirname, bool unlink_all) RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
{ {
DIR *temp_dir; DIR *temp_dir;
struct dirent *temp_de; struct dirent *temp_de;
...@@ -3060,6 +3069,9 @@ RemovePgTempFilesInDir(const char *tmpdirname, bool unlink_all) ...@@ -3060,6 +3069,9 @@ RemovePgTempFilesInDir(const char *tmpdirname, bool unlink_all)
temp_dir = AllocateDir(tmpdirname); temp_dir = AllocateDir(tmpdirname);
if (temp_dir == NULL && errno == ENOENT && missing_ok)
return;
while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL) while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
{ {
if (strcmp(temp_de->d_name, ".") == 0 || if (strcmp(temp_de->d_name, ".") == 0 ||
...@@ -3087,7 +3099,7 @@ RemovePgTempFilesInDir(const char *tmpdirname, bool unlink_all) ...@@ -3087,7 +3099,7 @@ RemovePgTempFilesInDir(const char *tmpdirname, bool unlink_all)
if (S_ISDIR(statbuf.st_mode)) if (S_ISDIR(statbuf.st_mode))
{ {
/* recursively remove contents, then directory itself */ /* recursively remove contents, then directory itself */
RemovePgTempFilesInDir(rm_path, true); RemovePgTempFilesInDir(rm_path, false, true);
if (rmdir(rm_path) < 0) if (rmdir(rm_path) < 0)
ereport(LOG, ereport(LOG,
......
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