Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit54428db

Browse files
committed
Fix error handling in temp-file deletion with log_temp_files active.
The original coding in FileClose() reset the file-is-temp flag beforeunlinking the file, so that if control came back through due to an error,it wouldn't try to unlink the file twice. This was correct when written,but when the log_temp_files feature was added, the logging action was putin between those two steps. An error occurring during the logging action--- such as a query cancel --- would result in the unlink not getting doneat all, as in recent report from Michael Glaesemann.To fix this, make sure that we do both the stat and the unlink before doinganything that could conceivably CHECK_FOR_INTERRUPTS. There is a judgmentcall here, which is which log message to emit first: if you can see onlyone, which should it be? I chose to log unlink failure at the risk oflosing the log_temp_files log message --- after all, if the unlink doesfail, the temp file is still there for you to see.Back-patch to all versions that have log_temp_files. The code was OKbefore that.
1 parent854ae8c commit54428db

File tree

1 file changed

+33
-6
lines changed
  • src/backend/storage/file

1 file changed

+33
-6
lines changed

‎src/backend/storage/file/fd.c

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,6 @@ void
10321032
FileClose(Filefile)
10331033
{
10341034
Vfd*vfdP;
1035-
structstatfilestats;
10361035

10371036
Assert(FileIsValid(file));
10381037

@@ -1055,15 +1054,36 @@ FileClose(File file)
10551054
}
10561055

10571056
/*
1058-
* Delete the file if it was temporary
1057+
* Delete the file if it was temporary, and make a log entry if wanted
10591058
*/
10601059
if (vfdP->fdstate&FD_TEMPORARY)
10611060
{
1062-
/* reset flag so that die() interrupt won't cause problems */
1061+
/*
1062+
* If we get an error, as could happen within the ereport/elog calls,
1063+
* we'll come right back here during transaction abort. Reset the
1064+
* flag to ensure that we can't get into an infinite loop. This code
1065+
* is arranged to ensure that the worst-case consequence is failing
1066+
* to emit log message(s), not failing to attempt the unlink.
1067+
*/
10631068
vfdP->fdstate &= ~FD_TEMPORARY;
1069+
10641070
if (log_temp_files >=0)
10651071
{
1066-
if (stat(vfdP->fileName,&filestats)==0)
1072+
structstatfilestats;
1073+
intstat_errno;
1074+
1075+
/* first try the stat() */
1076+
if (stat(vfdP->fileName,&filestats))
1077+
stat_errno=errno;
1078+
else
1079+
stat_errno=0;
1080+
1081+
/* in any case do the unlink */
1082+
if (unlink(vfdP->fileName))
1083+
elog(LOG,"could not unlink file \"%s\": %m",vfdP->fileName);
1084+
1085+
/* and last report the stat results */
1086+
if (stat_errno==0)
10671087
{
10681088
if ((filestats.st_size /1024) >=log_temp_files)
10691089
ereport(LOG,
@@ -1072,10 +1092,17 @@ FileClose(File file)
10721092
(unsigned long)filestats.st_size)));
10731093
}
10741094
else
1095+
{
1096+
errno=stat_errno;
10751097
elog(LOG,"could not stat file \"%s\": %m",vfdP->fileName);
1098+
}
1099+
}
1100+
else
1101+
{
1102+
/* easy case, just do the unlink */
1103+
if (unlink(vfdP->fileName))
1104+
elog(LOG,"could not unlink file \"%s\": %m",vfdP->fileName);
10761105
}
1077-
if (unlink(vfdP->fileName))
1078-
elog(LOG,"could not unlink file \"%s\": %m",vfdP->fileName);
10791106
}
10801107

10811108
/* Unregister it from the resource owner */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp