Skip to content

Commit c89a0dd

Browse files
committed
Repair longstanding bug in slru/clog logic: it is possible for two backends
to try to create a log segment file concurrently, but the code erroneously specified O_EXCL to open(), resulting in a needless failure. Before 7.4, it was even a PANIC condition :-(. Correct code is actually simpler than what we had, because we can just say O_CREAT to start with and not need a second open() call. I believe this accounts for several recent reports of hard-to-reproduce "could not create file ...: File exists" errors in both pg_clog and pg_subtrans.
1 parent 4789e98 commit c89a0dd

File tree

1 file changed

+10
-25
lines changed
  • src/backend/access/transam

1 file changed

+10
-25
lines changed

src/backend/access/transam/slru.c

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
4242
* Portions Copyright (c) 1994, Regents of the University of California
4343
*
44-
* $PostgreSQL: pgsql/src/backend/access/transam/slru.c,v 1.33 2005/12/06 23:08:32 tgl Exp $
44+
* $PostgreSQL: pgsql/src/backend/access/transam/slru.c,v 1.34 2006/01/21 04:38:21 tgl Exp $
4545
*
4646
*-------------------------------------------------------------------------
4747
*/
@@ -128,7 +128,6 @@ typedef struct SlruFlushData
128128
typedef enum
129129
{
130130
SLRU_OPEN_FAILED,
131-
SLRU_CREATE_FAILED,
132131
SLRU_SEEK_FAILED,
133132
SLRU_READ_FAILED,
134133
SLRU_WRITE_FAILED,
@@ -652,26 +651,19 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruFlush fdata)
652651
* transactions that have already been truncated from the commit log.
653652
* Easiest way to deal with that is to accept references to
654653
* nonexistent files here and in SlruPhysicalReadPage.)
654+
*
655+
* Note: it is possible for more than one backend to be executing
656+
* this code simultaneously for different pages of the same file.
657+
* Hence, don't use O_EXCL or O_TRUNC or anything like that.
655658
*/
656659
SlruFileName(ctl, path, segno);
657-
fd = BasicOpenFile(path, O_RDWR | PG_BINARY, S_IRUSR | S_IWUSR);
660+
fd = BasicOpenFile(path, O_RDWR | O_CREAT | PG_BINARY,
661+
S_IRUSR | S_IWUSR);
658662
if (fd < 0)
659663
{
660-
if (errno != ENOENT)
661-
{
662-
slru_errcause = SLRU_OPEN_FAILED;
663-
slru_errno = errno;
664-
return false;
665-
}
666-
667-
fd = BasicOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
668-
S_IRUSR | S_IWUSR);
669-
if (fd < 0)
670-
{
671-
slru_errcause = SLRU_CREATE_FAILED;
672-
slru_errno = errno;
673-
return false;
674-
}
664+
slru_errcause = SLRU_OPEN_FAILED;
665+
slru_errno = errno;
666+
return false;
675667
}
676668

677669
if (fdata)
@@ -763,13 +755,6 @@ SlruReportIOError(SlruCtl ctl, int pageno, TransactionId xid)
763755
errdetail("could not open file \"%s\": %m",
764756
path)));
765757
break;
766-
case SLRU_CREATE_FAILED:
767-
ereport(ERROR,
768-
(errcode_for_file_access(),
769-
errmsg("could not access status of transaction %u", xid),
770-
errdetail("could not create file \"%s\": %m",
771-
path)));
772-
break;
773758
case SLRU_SEEK_FAILED:
774759
ereport(ERROR,
775760
(errcode_for_file_access(),

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy