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

Commit9989d37

Browse files
committed
Remove XLogFileNameP() from the tree
XLogFileNameP() is a wrapper routine able to build a palloc'd string fora WAL segment name, which is used for error string generation. Therewere several code paths where it gets called in a critical section,where memory allocation is not allowed. This results in triggeringan assertion failure instead of generating the wanted error message.Another, more annoying, problem is that if the allocation to generatethe WAL segment name fails on OOM, then the failure would be escalatedto a PANIC.This removes the routine and all its callers are replaced with a logicusing a fixed-size buffer. This way, all the existing mistakes arefixed and future ones are prevented.Author: Masahiko SawadaReviewed-by: Michael Paquier, Álvaro HerreraDiscussion:https://postgr.es/m/CA+fd4k5gC9H4uoWMLg9K_QfNrnkkdEw+-AFveob9YX7z8JnKTA@mail.gmail.com
1 parente5532f1 commit9989d37

File tree

6 files changed

+95
-43
lines changed

6 files changed

+95
-43
lines changed

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

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2499,14 +2499,21 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
24992499
pgstat_report_wait_end();
25002500
if (written <=0)
25012501
{
2502+
charxlogfname[MAXFNAMELEN];
2503+
intsave_errno;
2504+
25022505
if (errno==EINTR)
25032506
continue;
2507+
2508+
save_errno=errno;
2509+
XLogFileName(xlogfname,ThisTimeLineID,openLogSegNo,
2510+
wal_segment_size);
2511+
errno=save_errno;
25042512
ereport(PANIC,
25052513
(errcode_for_file_access(),
25062514
errmsg("could not write to log file %s "
25072515
"at offset %u, length %zu: %m",
2508-
XLogFileNameP(ThisTimeLineID,openLogSegNo),
2509-
startoffset,nleft)));
2516+
xlogfname,startoffset,nleft)));
25102517
}
25112518
nleft-=written;
25122519
from+=written;
@@ -3792,10 +3799,17 @@ XLogFileClose(void)
37923799
#endif
37933800

37943801
if (close(openLogFile)!=0)
3802+
{
3803+
charxlogfname[MAXFNAMELEN];
3804+
intsave_errno=errno;
3805+
3806+
XLogFileName(xlogfname,ThisTimeLineID,openLogSegNo,wal_segment_size);
3807+
errno=save_errno;
37953808
ereport(PANIC,
37963809
(errcode_for_file_access(),
3797-
errmsg("could not close file \"%s\": %m",
3798-
XLogFileNameP(ThisTimeLineID,openLogSegNo))));
3810+
errmsg("could not close file \"%s\": %m",xlogfname)));
3811+
}
3812+
37993813
openLogFile=-1;
38003814
}
38013815

@@ -5510,10 +5524,17 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
55105524
fd=XLogFileInit(startLogSegNo,&use_existent, true);
55115525

55125526
if (close(fd)!=0)
5527+
{
5528+
charxlogfname[MAXFNAMELEN];
5529+
intsave_errno=errno;
5530+
5531+
XLogFileName(xlogfname,ThisTimeLineID,openLogSegNo,
5532+
wal_segment_size);
5533+
errno=save_errno;
55135534
ereport(ERROR,
55145535
(errcode_for_file_access(),
5515-
errmsg("could not close file \"%s\": %m",
5516-
XLogFileNameP(ThisTimeLineID,startLogSegNo))));
5536+
errmsg("could not close file \"%s\": %m",xlogfname)));
5537+
}
55175538
}
55185539

55195540
/*
@@ -10079,10 +10100,19 @@ assign_xlog_sync_method(int new_sync_method, void *extra)
1007910100
{
1008010101
pgstat_report_wait_start(WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN);
1008110102
if (pg_fsync(openLogFile)!=0)
10103+
{
10104+
charxlogfname[MAXFNAMELEN];
10105+
intsave_errno;
10106+
10107+
save_errno=errno;
10108+
XLogFileName(xlogfname,ThisTimeLineID,openLogSegNo,
10109+
wal_segment_size);
10110+
errno=save_errno;
1008210111
ereport(PANIC,
1008310112
(errcode_for_file_access(),
10084-
errmsg("could not fsync file \"%s\": %m",
10085-
XLogFileNameP(ThisTimeLineID,openLogSegNo))));
10113+
errmsg("could not fsync file \"%s\": %m",xlogfname)));
10114+
}
10115+
1008610116
pgstat_report_wait_end();
1008710117
if (get_sync_bit(sync_method)!=get_sync_bit(new_sync_method))
1008810118
XLogFileClose();
@@ -10100,32 +10130,25 @@ assign_xlog_sync_method(int new_sync_method, void *extra)
1010010130
void
1010110131
issue_xlog_fsync(intfd,XLogSegNosegno)
1010210132
{
10133+
char*msg=NULL;
10134+
1010310135
pgstat_report_wait_start(WAIT_EVENT_WAL_SYNC);
1010410136
switch (sync_method)
1010510137
{
1010610138
caseSYNC_METHOD_FSYNC:
1010710139
if (pg_fsync_no_writethrough(fd)!=0)
10108-
ereport(PANIC,
10109-
(errcode_for_file_access(),
10110-
errmsg("could not fsync file \"%s\": %m",
10111-
XLogFileNameP(ThisTimeLineID,segno))));
10140+
msg=_("could not fsync file \"%s\": %m");
1011210141
break;
1011310142
#ifdefHAVE_FSYNC_WRITETHROUGH
1011410143
caseSYNC_METHOD_FSYNC_WRITETHROUGH:
1011510144
if (pg_fsync_writethrough(fd)!=0)
10116-
ereport(PANIC,
10117-
(errcode_for_file_access(),
10118-
errmsg("could not fsync write-through file \"%s\": %m",
10119-
XLogFileNameP(ThisTimeLineID,segno))));
10145+
msg=_("could not fsync write-through file \"%s\": %m");
1012010146
break;
1012110147
#endif
1012210148
#ifdefHAVE_FDATASYNC
1012310149
caseSYNC_METHOD_FDATASYNC:
1012410150
if (pg_fdatasync(fd)!=0)
10125-
ereport(PANIC,
10126-
(errcode_for_file_access(),
10127-
errmsg("could not fdatasync file \"%s\": %m",
10128-
XLogFileNameP(ThisTimeLineID,segno))));
10151+
msg=_("could not fdatasync file \"%s\": %m");
1012910152
break;
1013010153
#endif
1013110154
caseSYNC_METHOD_OPEN:
@@ -10136,19 +10159,22 @@ issue_xlog_fsync(int fd, XLogSegNo segno)
1013610159
elog(PANIC,"unrecognized wal_sync_method: %d",sync_method);
1013710160
break;
1013810161
}
10139-
pgstat_report_wait_end();
10140-
}
1014110162

10142-
/*
10143-
* Return the filename of given log segment, as a palloc'd string.
10144-
*/
10145-
char*
10146-
XLogFileNameP(TimeLineIDtli,XLogSegNosegno)
10147-
{
10148-
char*result=palloc(MAXFNAMELEN);
10163+
/* PANIC if failed to fsync */
10164+
if (msg)
10165+
{
10166+
charxlogfname[MAXFNAMELEN];
10167+
intsave_errno=errno;
1014910168

10150-
XLogFileName(result,tli,segno,wal_segment_size);
10151-
returnresult;
10169+
XLogFileName(xlogfname,ThisTimeLineID,openLogSegNo,
10170+
wal_segment_size);
10171+
errno=save_errno;
10172+
ereport(PANIC,
10173+
(errcode_for_file_access(),
10174+
errmsg(msg,xlogfname)));
10175+
}
10176+
10177+
pgstat_report_wait_end();
1015210178
}
1015310179

1015410180
/*

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@ XLogReadDetermineTimeline(XLogReaderState *state, XLogRecPtr wantPage, uint32 wa
776776

777777
/* openSegment callback for WALRead */
778778
staticint
779-
wal_segment_open(XLogSegNonextSegNo,WALSegmentContext*segcxt,
779+
wal_segment_open(XLogSegNonextSegNo,WALSegmentContext*segcxt,
780780
TimeLineID*tli_p)
781781
{
782782
TimeLineIDtli=*tli_p;
@@ -944,7 +944,9 @@ void
944944
WALReadRaiseError(WALReadError*errinfo)
945945
{
946946
WALOpenSegment*seg=&errinfo->wre_seg;
947-
char*fname=XLogFileNameP(seg->ws_tli,seg->ws_segno);
947+
charfname[MAXFNAMELEN];
948+
949+
XLogFileName(fname,seg->ws_tli,seg->ws_segno,wal_segment_size);
948950

949951
if (errinfo->wre_read<0)
950952
{

‎src/backend/replication/walreceiver.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -576,17 +576,17 @@ WalReceiverMain(void)
576576
charxlogfname[MAXFNAMELEN];
577577

578578
XLogWalRcvFlush(false);
579+
XLogFileName(xlogfname,recvFileTLI,recvSegNo,wal_segment_size);
579580
if (close(recvFile)!=0)
580581
ereport(PANIC,
581582
(errcode_for_file_access(),
582583
errmsg("could not close log segment %s: %m",
583-
XLogFileNameP(recvFileTLI,recvSegNo))));
584+
xlogfname)));
584585

585586
/*
586587
* Create .done file forcibly to prevent the streamed segment from
587588
* being archived later.
588589
*/
589-
XLogFileName(xlogfname,recvFileTLI,recvSegNo,wal_segment_size);
590590
if (XLogArchiveMode!=ARCHIVE_MODE_ALWAYS)
591591
XLogArchiveForceDone(xlogfname);
592592
else
@@ -900,6 +900,8 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
900900

901901
XLogWalRcvFlush(false);
902902

903+
XLogFileName(xlogfname,recvFileTLI,recvSegNo,wal_segment_size);
904+
903905
/*
904906
* XLOG segment files will be re-read by recovery in startup
905907
* process soon, so we don't advise the OS to release cache
@@ -909,13 +911,12 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
909911
ereport(PANIC,
910912
(errcode_for_file_access(),
911913
errmsg("could not close log segment %s: %m",
912-
XLogFileNameP(recvFileTLI,recvSegNo))));
914+
xlogfname)));
913915

914916
/*
915917
* Create .done file forcibly to prevent the streamed segment
916918
* from being archived later.
917919
*/
918-
XLogFileName(xlogfname,recvFileTLI,recvSegNo,wal_segment_size);
919920
if (XLogArchiveMode!=ARCHIVE_MODE_ALWAYS)
920921
XLogArchiveForceDone(xlogfname);
921922
else
@@ -943,11 +944,18 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
943944
if (recvOff!=startoff)
944945
{
945946
if (lseek(recvFile, (off_t)startoff,SEEK_SET)<0)
947+
{
948+
charxlogfname[MAXFNAMELEN];
949+
intsave_errno=errno;
950+
951+
XLogFileName(xlogfname,recvFileTLI,recvSegNo,wal_segment_size);
952+
errno=save_errno;
946953
ereport(PANIC,
947954
(errcode_for_file_access(),
948955
errmsg("could not seek in log segment %s to offset %u: %m",
949-
XLogFileNameP(recvFileTLI,recvSegNo),
950-
startoff)));
956+
xlogfname,startoff)));
957+
}
958+
951959
recvOff=startoff;
952960
}
953961

@@ -957,15 +965,21 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
957965
byteswritten=write(recvFile,buf,segbytes);
958966
if (byteswritten <=0)
959967
{
968+
charxlogfname[MAXFNAMELEN];
969+
intsave_errno;
970+
960971
/* if write didn't set errno, assume no disk space */
961972
if (errno==0)
962973
errno=ENOSPC;
974+
975+
save_errno=errno;
976+
XLogFileName(xlogfname,recvFileTLI,recvSegNo,wal_segment_size);
977+
errno=save_errno;
963978
ereport(PANIC,
964979
(errcode_for_file_access(),
965980
errmsg("could not write to log segment %s "
966981
"at offset %u, length %lu: %m",
967-
XLogFileNameP(recvFileTLI,recvSegNo),
968-
recvOff, (unsigned long)segbytes)));
982+
xlogfname,recvOff, (unsigned long)segbytes)));
969983
}
970984

971985
/* Update state for write */

‎src/backend/replication/walsender.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2434,10 +2434,17 @@ WalSndSegmentOpen(XLogSegNo nextSegNo, WALSegmentContext *segcxt,
24342434
* too old WAL segment that has already been removed or recycled.
24352435
*/
24362436
if (errno==ENOENT)
2437+
{
2438+
charxlogfname[MAXFNAMELEN];
2439+
intsave_errno=errno;
2440+
2441+
XLogFileName(xlogfname,*tli_p,nextSegNo,wal_segment_size);
2442+
errno=save_errno;
24372443
ereport(ERROR,
24382444
(errcode_for_file_access(),
24392445
errmsg("requested WAL segment %s has already been removed",
2440-
XLogFileNameP(*tli_p,nextSegNo))));
2446+
xlogfname)));
2447+
}
24412448
else
24422449
ereport(ERROR,
24432450
(errcode_for_file_access(),

‎src/include/access/xlog.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,6 @@ extern bool RecoveryIsPaused(void);
288288
externvoidSetRecoveryPause(boolrecoveryPause);
289289
externTimestampTzGetLatestXTime(void);
290290
externTimestampTzGetCurrentChunkReplayStartTime(void);
291-
externchar*XLogFileNameP(TimeLineIDtli,XLogSegNosegno);
292291

293292
externvoidUpdateControlFile(void);
294293
externuint64GetSystemIdentifier(void);

‎src/include/access/xlog_internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
152152
/* Length of XLog file name */
153153
#defineXLOG_FNAME_LEN 24
154154

155+
/*
156+
* Generate a WAL segment file name. Do not use this macro in a helper
157+
* function allocating the result generated.
158+
*/
155159
#defineXLogFileName(fname,tli,logSegNo,wal_segsz_bytes)\
156160
snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli,\
157161
(uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp