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

Commit2b3e467

Browse files
committed
Don't ERROR on PreallocXlogFiles() race condition.
Before a restartpoint finishes PreallocXlogFiles(), a startup processKeepFileRestoredFromArchive() call can unlink the preallocated segment.If a CHECKPOINT sql command had elicited the restartpoint experiencingthe race condition, that sql command failed. Moreover, the restartpointomitted its log_checkpoints message and some inessential resourcereclamation. Prevent the ERROR by skipping open() of the segment.Since these consequences are so minor, no back-patch.Discussion:https://postgr.es/m/20210202151416.GB3304930@rfd.leadboat.com
1 parent421484f commit2b3e467

File tree

3 files changed

+58
-27
lines changed

3 files changed

+58
-27
lines changed

‎src/backend/access/transam/xlog.c

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2424,7 +2424,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
24242424
boolispartialpage;
24252425
boollast_iteration;
24262426
boolfinishing_seg;
2427-
booladded;
24282427
intcurridx;
24292428
intnpages;
24302429
intstartidx;
@@ -2490,7 +2489,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
24902489
wal_segment_size);
24912490

24922491
/* create/use new log file */
2493-
openLogFile=XLogFileInit(openLogSegNo,&added);
2492+
openLogFile=XLogFileInit(openLogSegNo);
24942493
ReserveExternalFD();
24952494
}
24962495

@@ -3255,23 +3254,21 @@ XLogNeedsFlush(XLogRecPtr record)
32553254
}
32563255

32573256
/*
3258-
*Create a new XLOG file segment, or open a pre-existing one.
3257+
*Try to make a given XLOG file segment exist.
32593258
*
3260-
* logsegno: identify segment to be created/opened.
3259+
* logsegno: identify segment.
32613260
*
32623261
* *added: on return, true if this call raised the number of extant segments.
32633262
*
3264-
*Returns FD of opened file.
3263+
*path: on return, this char[MAXPGPATH] has the path to the logsegno file.
32653264
*
3266-
* Note: errors here are ERROR not PANIC because we might or might not be
3267-
* inside a critical section (eg, during checkpoint there is no reason to
3268-
* take down the system on failure). They will promote to PANIC if we are
3269-
* in a critical section.
3265+
* Returns -1 or FD of opened file. A -1 here is not an error; a caller
3266+
* wanting an open segment should attempt to open "path", which usually will
3267+
* succeed. (This is weird, but it's efficient for the callers.)
32703268
*/
3271-
int
3272-
XLogFileInit(XLogSegNologsegno,bool*added)
3269+
staticint
3270+
XLogFileInitInternal(XLogSegNologsegno,bool*added,char*path)
32733271
{
3274-
charpath[MAXPGPATH];
32753272
chartmppath[MAXPGPATH];
32763273
PGAlignedXLogBlockzbuffer;
32773274
XLogSegNoinstalled_segno;
@@ -3424,26 +3421,53 @@ XLogFileInit(XLogSegNo logsegno, bool *added)
34243421
*/
34253422
max_segno=logsegno+CheckPointSegments;
34263423
if (InstallXLogFileSegment(&installed_segno,tmppath, true,max_segno))
3424+
{
34273425
*added= true;
3426+
elog(DEBUG2,"done creating and filling new WAL file");
3427+
}
34283428
else
34293429
{
34303430
/*
34313431
* No need for any more future segments, or InstallXLogFileSegment()
3432-
* failed to rename the file into place. If the rename failed,opening
3433-
* the filebelow will fail.
3432+
* failed to rename the file into place. If the rename failed,a
3433+
*caller openingthe filemay fail.
34343434
*/
34353435
unlink(tmppath);
3436+
elog(DEBUG2,"abandoned new WAL file");
34363437
}
34373438

3439+
return-1;
3440+
}
3441+
3442+
/*
3443+
* Create a new XLOG file segment, or open a pre-existing one.
3444+
*
3445+
* logsegno: identify segment to be created/opened.
3446+
*
3447+
* Returns FD of opened file.
3448+
*
3449+
* Note: errors here are ERROR not PANIC because we might or might not be
3450+
* inside a critical section (eg, during checkpoint there is no reason to
3451+
* take down the system on failure). They will promote to PANIC if we are
3452+
* in a critical section.
3453+
*/
3454+
int
3455+
XLogFileInit(XLogSegNologsegno)
3456+
{
3457+
boolignore_added;
3458+
charpath[MAXPGPATH];
3459+
intfd;
3460+
3461+
fd=XLogFileInitInternal(logsegno,&ignore_added,path);
3462+
if (fd >=0)
3463+
returnfd;
3464+
34383465
/* Now open original target segment (might not be file I just made) */
34393466
fd=BasicOpenFile(path,O_RDWR |PG_BINARY |get_sync_bit(sync_method));
34403467
if (fd<0)
34413468
ereport(ERROR,
34423469
(errcode_for_file_access(),
34433470
errmsg("could not open file \"%s\": %m",path)));
3444-
3445-
elog(DEBUG2,"done creating and filling new WAL file");
3446-
34473471
returnfd;
34483472
}
34493473

@@ -3903,22 +3927,33 @@ XLogFileClose(void)
39033927
* High-volume systems will be OK once they've built up a sufficient set of
39043928
* recycled log segments, but the startup transient is likely to include
39053929
* a lot of segment creations by foreground processes, which is not so good.
3930+
*
3931+
* XLogFileInitInternal() can ereport(ERROR). All known causes indicate big
3932+
* trouble; for example, a full filesystem is one cause. The checkpoint WAL
3933+
* and/or ControlFile updates already completed. If a RequestCheckpoint()
3934+
* initiated the present checkpoint and an ERROR ends this function, the
3935+
* command that called RequestCheckpoint() fails. That's not ideal, but it's
3936+
* not worth contorting more functions to use caller-specified elevel values.
3937+
* (With or without RequestCheckpoint(), an ERROR forestalls some inessential
3938+
* reporting and resource reclamation.)
39063939
*/
39073940
staticvoid
39083941
PreallocXlogFiles(XLogRecPtrendptr)
39093942
{
39103943
XLogSegNo_logSegNo;
39113944
intlf;
39123945
booladded;
3946+
charpath[MAXPGPATH];
39133947
uint64offset;
39143948

39153949
XLByteToPrevSeg(endptr,_logSegNo,wal_segment_size);
39163950
offset=XLogSegmentOffset(endptr-1,wal_segment_size);
39173951
if (offset >= (uint32) (0.75*wal_segment_size))
39183952
{
39193953
_logSegNo++;
3920-
lf=XLogFileInit(_logSegNo,&added);
3921-
close(lf);
3954+
lf=XLogFileInitInternal(_logSegNo,&added,path);
3955+
if (lf >=0)
3956+
close(lf);
39223957
if (added)
39233958
CheckpointStats.ckpt_segs_added++;
39243959
}
@@ -5214,7 +5249,6 @@ BootStrapXLOG(void)
52145249
XLogLongPageHeaderlongpage;
52155250
XLogRecord*record;
52165251
char*recptr;
5217-
booladded;
52185252
uint64sysidentifier;
52195253
structtimevaltv;
52205254
pg_crc32ccrc;
@@ -5311,7 +5345,7 @@ BootStrapXLOG(void)
53115345
record->xl_crc=crc;
53125346

53135347
/* Create first XLOG segment file */
5314-
openLogFile=XLogFileInit(1,&added);
5348+
openLogFile=XLogFileInit(1);
53155349

53165350
/*
53175351
* We needn't bother with Reserve/ReleaseExternalFD here, since we'll
@@ -5617,10 +5651,9 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
56175651
* The switch happened at a segment boundary, so just create the next
56185652
* segment on the new timeline.
56195653
*/
5620-
booladded;
56215654
intfd;
56225655

5623-
fd=XLogFileInit(startLogSegNo,&added);
5656+
fd=XLogFileInit(startLogSegNo);
56245657

56255658
if (close(fd)!=0)
56265659
{

‎src/backend/replication/walreceiver.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -885,8 +885,6 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
885885

886886
if (recvFile<0|| !XLByteInSeg(recptr,recvSegNo,wal_segment_size))
887887
{
888-
booladded;
889-
890888
/*
891889
* fsync() and close current file before we switch to next one. We
892890
* would otherwise have to reopen this file to fsync it later
@@ -923,7 +921,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
923921

924922
/* Create/use new log file */
925923
XLByteToSeg(recptr,recvSegNo,wal_segment_size);
926-
recvFile=XLogFileInit(recvSegNo,&added);
924+
recvFile=XLogFileInit(recvSegNo);
927925
recvFileTLI=ThisTimeLineID;
928926
}
929927

‎src/include/access/xlog.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ extern XLogRecPtr XLogInsertRecord(struct XLogRecData *rdata,
296296
externvoidXLogFlush(XLogRecPtrRecPtr);
297297
externboolXLogBackgroundFlush(void);
298298
externboolXLogNeedsFlush(XLogRecPtrRecPtr);
299-
externintXLogFileInit(XLogSegNosegno,bool*added);
299+
externintXLogFileInit(XLogSegNosegno);
300300
externintXLogFileOpen(XLogSegNosegno);
301301

302302
externvoidCheckXLogRemoved(XLogSegNosegno,TimeLineIDtli);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp