fix_XLogFileNameP_v2.patch
application/octet-stream
Filename: fix_XLogFileNameP_v2.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
Series: patch v2
| File | + | − |
|---|---|---|
| src/backend/access/transam/xlog.c | 56 | 31 |
| src/backend/access/transam/xlogutils.c | 3 | 1 |
| src/backend/replication/walreceiver.c | 22 | 8 |
| src/backend/replication/walsender.c | 8 | 1 |
| src/include/access/xlog.h | 0 | 1 |
| src/include/access/xlog_internal.h | 6 | 0 |
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 5f0ee50092..fb1262a175 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2499,14 +2499,21 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
pgstat_report_wait_end();
if (written <= 0)
{
+ char xlogfname[MAXFNAMELEN];
+ int save_errno;
+
if (errno == EINTR)
continue;
+
+ save_errno = errno;
+ XLogFileName(xlogfname, ThisTimeLineID, openLogSegNo,
+ wal_segment_size);
+ errno = save_errno;
ereport(PANIC,
(errcode_for_file_access(),
errmsg("could not write to log file %s "
"at offset %u, length %zu: %m",
- XLogFileNameP(ThisTimeLineID, openLogSegNo),
- startoffset, nleft)));
+ xlogfname, startoffset, nleft)));
}
nleft -= written;
from += written;
@@ -3792,10 +3799,17 @@ XLogFileClose(void)
#endif
if (close(openLogFile) != 0)
+ {
+ char xlogfname[MAXFNAMELEN];
+ int save_errno = errno;
+
+ XLogFileName(xlogfname, ThisTimeLineID, openLogSegNo, wal_segment_size);
+ errno = save_errno;
ereport(PANIC,
(errcode_for_file_access(),
- errmsg("could not close file \"%s\": %m",
- XLogFileNameP(ThisTimeLineID, openLogSegNo))));
+ errmsg("could not close file \"%s\": %m", xlogfname)));
+ }
+
openLogFile = -1;
}
@@ -5510,10 +5524,17 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
fd = XLogFileInit(startLogSegNo, &use_existent, true);
if (close(fd) != 0)
+ {
+ char xlogfname[MAXFNAMELEN];
+ int save_errno = errno;
+
+ XLogFileName(xlogfname, ThisTimeLineID, openLogSegNo,
+ wal_segment_size);
+ errno = save_errno;
ereport(ERROR,
(errcode_for_file_access(),
- errmsg("could not close file \"%s\": %m",
- XLogFileNameP(ThisTimeLineID, startLogSegNo))));
+ errmsg("could not close file \"%s\": %m", xlogfname)));
+ }
}
/*
@@ -10079,10 +10100,18 @@ assign_xlog_sync_method(int new_sync_method, void *extra)
{
pgstat_report_wait_start(WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN);
if (pg_fsync(openLogFile) != 0)
+ {
+ char xlogfname[MAXFNAMELEN];
+ int save_errno;
+
+ save_errno = errno;
+ XLogFileName(xlogfname, ThisTimeLineID, openLogSegNo,
+ wal_segment_size);
ereport(PANIC,
(errcode_for_file_access(),
- errmsg("could not fsync file \"%s\": %m",
- XLogFileNameP(ThisTimeLineID, openLogSegNo))));
+ errmsg("could not fsync file \"%s\": %m", xlogfname)));
+ }
+
pgstat_report_wait_end();
if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method))
XLogFileClose();
@@ -10100,32 +10129,25 @@ assign_xlog_sync_method(int new_sync_method, void *extra)
void
issue_xlog_fsync(int fd, XLogSegNo segno)
{
+ char *msg = NULL;
+
pgstat_report_wait_start(WAIT_EVENT_WAL_SYNC);
switch (sync_method)
{
case SYNC_METHOD_FSYNC:
if (pg_fsync_no_writethrough(fd) != 0)
- ereport(PANIC,
- (errcode_for_file_access(),
- errmsg("could not fsync file \"%s\": %m",
- XLogFileNameP(ThisTimeLineID, segno))));
+ msg = _("could not fsync file \"%s\": %m");
break;
#ifdef HAVE_FSYNC_WRITETHROUGH
case SYNC_METHOD_FSYNC_WRITETHROUGH:
if (pg_fsync_writethrough(fd) != 0)
- ereport(PANIC,
- (errcode_for_file_access(),
- errmsg("could not fsync write-through file \"%s\": %m",
- XLogFileNameP(ThisTimeLineID, segno))));
+ msg = _("could not fsync write-through file \"%s\": %m");
break;
#endif
#ifdef HAVE_FDATASYNC
case SYNC_METHOD_FDATASYNC:
if (pg_fdatasync(fd) != 0)
- ereport(PANIC,
- (errcode_for_file_access(),
- errmsg("could not fdatasync file \"%s\": %m",
- XLogFileNameP(ThisTimeLineID, segno))));
+ msg = _("could not fdatasync file \"%s\": %m");
break;
#endif
case SYNC_METHOD_OPEN:
@@ -10136,19 +10158,22 @@ issue_xlog_fsync(int fd, XLogSegNo segno)
elog(PANIC, "unrecognized wal_sync_method: %d", sync_method);
break;
}
- pgstat_report_wait_end();
-}
-/*
- * Return the filename of given log segment, as a palloc'd string.
- */
-char *
-XLogFileNameP(TimeLineID tli, XLogSegNo segno)
-{
- char *result = palloc(MAXFNAMELEN);
+ /* PANIC if failed to fsync */
+ if (msg)
+ {
+ char xlogfname[MAXFNAMELEN];
+ int save_errno = errno;
- XLogFileName(result, tli, segno, wal_segment_size);
- return result;
+ XLogFileName(xlogfname, ThisTimeLineID, openLogSegNo,
+ wal_segment_size);
+ errno = save_errno;
+ ereport(PANIC,
+ (errcode_for_file_access(),
+ errmsg(msg, xlogfname)));
+ }
+
+ pgstat_report_wait_end();
}
/*
diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c
index 446760ed6e..ca73ef5131 100644
--- a/src/backend/access/transam/xlogutils.c
+++ b/src/backend/access/transam/xlogutils.c
@@ -944,7 +944,9 @@ void
WALReadRaiseError(WALReadError *errinfo)
{
WALOpenSegment *seg = &errinfo->wre_seg;
- char *fname = XLogFileNameP(seg->ws_tli, seg->ws_segno);
+ char fname[MAXFNAMELEN];
+
+ XLogFileName(fname, seg->ws_tli, seg->ws_segno, wal_segment_size);
if (errinfo->wre_read < 0)
{
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index 72acb10767..9214ca6526 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -576,17 +576,17 @@ WalReceiverMain(void)
char xlogfname[MAXFNAMELEN];
XLogWalRcvFlush(false);
+ XLogFileName(xlogfname, recvFileTLI, recvSegNo, wal_segment_size);
if (close(recvFile) != 0)
ereport(PANIC,
(errcode_for_file_access(),
errmsg("could not close log segment %s: %m",
- XLogFileNameP(recvFileTLI, recvSegNo))));
+ xlogfname)));
/*
* Create .done file forcibly to prevent the streamed segment from
* being archived later.
*/
- XLogFileName(xlogfname, recvFileTLI, recvSegNo, wal_segment_size);
if (XLogArchiveMode != ARCHIVE_MODE_ALWAYS)
XLogArchiveForceDone(xlogfname);
else
@@ -900,6 +900,8 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
XLogWalRcvFlush(false);
+ XLogFileName(xlogfname, recvFileTLI, recvSegNo, wal_segment_size);
+
/*
* XLOG segment files will be re-read by recovery in startup
* process soon, so we don't advise the OS to release cache
@@ -909,13 +911,12 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
ereport(PANIC,
(errcode_for_file_access(),
errmsg("could not close log segment %s: %m",
- XLogFileNameP(recvFileTLI, recvSegNo))));
+ xlogfname)));
/*
* Create .done file forcibly to prevent the streamed segment
* from being archived later.
*/
- XLogFileName(xlogfname, recvFileTLI, recvSegNo, wal_segment_size);
if (XLogArchiveMode != ARCHIVE_MODE_ALWAYS)
XLogArchiveForceDone(xlogfname);
else
@@ -943,11 +944,18 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
if (recvOff != startoff)
{
if (lseek(recvFile, (off_t) startoff, SEEK_SET) < 0)
+ {
+ char xlogfname[MAXFNAMELEN];
+ int save_errno = errno;
+
+ XLogFileName(xlogfname, recvFileTLI, recvSegNo, wal_segment_size);
+ errno = save_errno;
ereport(PANIC,
(errcode_for_file_access(),
errmsg("could not seek in log segment %s to offset %u: %m",
- XLogFileNameP(recvFileTLI, recvSegNo),
- startoff)));
+ xlogfname, startoff)));
+ }
+
recvOff = startoff;
}
@@ -957,15 +965,21 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
byteswritten = write(recvFile, buf, segbytes);
if (byteswritten <= 0)
{
+ char xlogfname[MAXFNAMELEN];
+ int save_errno;
+
/* if write didn't set errno, assume no disk space */
if (errno == 0)
errno = ENOSPC;
+
+ save_errno = errno;
+ XLogFileName(xlogfname, recvFileTLI, recvSegNo, wal_segment_size);
+ errno = save_errno;
ereport(PANIC,
(errcode_for_file_access(),
errmsg("could not write to log segment %s "
"at offset %u, length %lu: %m",
- XLogFileNameP(recvFileTLI, recvSegNo),
- recvOff, (unsigned long) segbytes)));
+ xlogfname, recvOff, (unsigned long) segbytes)));
}
/* Update state for write */
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 8bafa65e50..5fcdec5f21 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -2434,10 +2434,17 @@ WalSndSegmentOpen(XLogSegNo nextSegNo, WALSegmentContext *segcxt,
* too old WAL segment that has already been removed or recycled.
*/
if (errno == ENOENT)
+ {
+ char xlogfname[MAXFNAMELEN];
+ int save_errno = errno;
+
+ XLogFileName(xlogfname, *tli_p, nextSegNo, wal_segment_size);
+ errno = save_errno;
ereport(ERROR,
(errcode_for_file_access(),
errmsg("requested WAL segment %s has already been removed",
- XLogFileNameP(*tli_p, nextSegNo))));
+ xlogfname)));
+ }
else
ereport(ERROR,
(errcode_for_file_access(),
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index d519252aad..9b588c87a5 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -288,7 +288,6 @@ extern bool RecoveryIsPaused(void);
extern void SetRecoveryPause(bool recoveryPause);
extern TimestampTz GetLatestXTime(void);
extern TimestampTz GetCurrentChunkReplayStartTime(void);
-extern char *XLogFileNameP(TimeLineID tli, XLogSegNo segno);
extern void UpdateControlFile(void);
extern uint64 GetSystemIdentifier(void);
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index e7e10beb4c..ba8e0f8d9f 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -152,6 +152,12 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
/* Length of XLog file name */
#define XLOG_FNAME_LEN 24
+/*
+ * Write xlog file name to fname. We used to have a helper function that returns
+ * the xlog file name as a palloc'd string. But we will never need such a function
+ * because it cannot be used during the critical section and it is hard to fix so
+ * that it is never misused.
+ */
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes) \
snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, \
(uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \