Alvaro Herrera <alvherre@xxxxxxxxxxxxxxxxx> writes: > Excerpts from Tom Lane's message of lun nov 08 22:29:28 -0300 2010: >> I think we need to re-order the operations there to ensure that the >> unlink will still happen if the ereport gets interrupted. > Would it work to put the removal inside a PG_CATCH block? Well, that still begs the question of what to do exactly. After some thought I believe the attached is the best fix. regards, tom lane
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index d9ab5e1ea2452131c2778acca6ad913ad4b333af..fd5ec7805fdcaedf73c3fa6aaa1a35970cf8e6db 100644 *** a/src/backend/storage/file/fd.c --- b/src/backend/storage/file/fd.c *************** void *** 1032,1038 **** FileClose(File file) { Vfd *vfdP; - struct stat filestats; Assert(FileIsValid(file)); --- 1032,1037 ---- *************** FileClose(File file) *** 1055,1069 **** } /* ! * Delete the file if it was temporary */ if (vfdP->fdstate & FD_TEMPORARY) { ! /* reset flag so that die() interrupt won't cause problems */ vfdP->fdstate &= ~FD_TEMPORARY; if (log_temp_files >= 0) { ! if (stat(vfdP->fileName, &filestats) == 0) { if ((filestats.st_size / 1024) >= log_temp_files) ereport(LOG, --- 1054,1089 ---- } /* ! * Delete the file if it was temporary, and make a log entry if wanted */ if (vfdP->fdstate & FD_TEMPORARY) { ! /* ! * If we get an error, as could happen within the ereport/elog calls, ! * we'll come right back here during transaction abort. Reset the ! * flag to ensure that we can't get into an infinite loop. This code ! * is arranged to ensure that the worst-case consequence is failing ! * to emit log message(s), not failing to attempt the unlink. ! */ vfdP->fdstate &= ~FD_TEMPORARY; + if (log_temp_files >= 0) { ! struct stat filestats; ! int stat_errno; ! ! /* first try the stat() */ ! if (stat(vfdP->fileName, &filestats)) ! stat_errno = errno; ! else ! stat_errno = 0; ! ! /* in any case do the unlink */ ! if (unlink(vfdP->fileName)) ! elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName); ! ! /* and last report the stat results */ ! if (stat_errno == 0) { if ((filestats.st_size / 1024) >= log_temp_files) ereport(LOG, *************** FileClose(File file) *** 1072,1081 **** (unsigned long) filestats.st_size))); } else elog(LOG, "could not stat file \"%s\": %m", vfdP->fileName); } - if (unlink(vfdP->fileName)) - elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName); } /* Unregister it from the resource owner */ --- 1092,1108 ---- (unsigned long) filestats.st_size))); } else + { + errno = stat_errno; elog(LOG, "could not stat file \"%s\": %m", vfdP->fileName); + } + } + else + { + /* easy case, just do the unlink */ + if (unlink(vfdP->fileName)) + elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName); } } /* Unregister it from the resource owner */
-- Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-general