Skip to content

Commit 7abc685

Browse files
committed
Refactor WAL segment copying code.
* Remove unused argument "dstfname" and related code from XLogFileCopy(). * Previously XLogFileCopy() returned a pstrdup'd string so that InstallXLogFileSegment() used it later. Since the pstrdup'd string was never free'd, there could be a risk of memory leak. It was almost harmless because the startup process exited just after calling XLogFileCopy(), it existed. This commit changes XLogFileCopy() so that it directly calls InstallXLogFileSegment() and doesn't call pstrdup() at all. Which fixes that memory leak problem. * Extend InstallXLogFileSegment() so that the caller can specify the log level. Which allows us to emit an error when InstallXLogFileSegment() fails a disk file access like link() and rename(). Previously it was always logged with LOG level and additionally needed to be logged with ERROR when we wanted to treat it as an error. Michael Paquier
1 parent d1b9582 commit 7abc685

File tree

1 file changed

+17
-37
lines changed
  • src/backend/access/transam

1 file changed

+17
-37
lines changed

src/backend/access/transam/xlog.c

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ static bool XLogCheckpointNeeded(XLogSegNo new_segno);
807807
static void XLogWrite(XLogwrtRqst WriteRqst, bool flexible);
808808
static bool InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
809809
bool find_free, XLogSegNo max_segno,
810-
bool use_lock);
810+
bool use_lock, int elevel);
811811
static int XLogFileRead(XLogSegNo segno, int emode, TimeLineID tli,
812812
int source, bool notexistOk);
813813
static int XLogFileReadAnyTLI(XLogSegNo segno, int emode, int source);
@@ -3012,7 +3012,7 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
30123012
max_segno = logsegno + CheckPointSegments;
30133013
if (!InstallXLogFileSegment(&installed_segno, tmppath,
30143014
*use_existent, max_segno,
3015-
use_lock))
3015+
use_lock, LOG))
30163016
{
30173017
/*
30183018
* No need for any more future segments, or InstallXLogFileSegment()
@@ -3041,18 +3041,16 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
30413041
/*
30423042
* Copy a WAL segment file in pg_xlog directory.
30433043
*
3044-
* dstfname destination filename
30453044
* srcfname source filename
30463045
* upto how much of the source file to copy? (the rest is filled with
30473046
* zeros)
3047+
* segno identify segment to install.
30483048
*
3049-
* If dstfname is not given, the file is created with a temporary filename,
3050-
* which is returned. Both filenames are relative to the pg_xlog directory.
3051-
*
3052-
* NB: Any existing file with the same name will be overwritten!
3049+
* The file is first copied with a temporary filename, and then installed as
3050+
* a newly-created segment.
30533051
*/
3054-
static char *
3055-
XLogFileCopy(char *dstfname, char *srcfname, int upto)
3052+
static void
3053+
XLogFileCopy(char *srcfname, int upto, XLogSegNo segno)
30563054
{
30573055
char srcpath[MAXPGPATH];
30583056
char tmppath[MAXPGPATH];
@@ -3150,25 +3148,9 @@ XLogFileCopy(char *dstfname, char *srcfname, int upto)
31503148

31513149
CloseTransientFile(srcfd);
31523150

3153-
/*
3154-
* Now move the segment into place with its final name. (Or just return
3155-
* the path to the file we created, if the caller wants to handle the rest
3156-
* on its own.)
3157-
*/
3158-
if (dstfname)
3159-
{
3160-
char dstpath[MAXPGPATH];
3161-
3162-
snprintf(dstpath, MAXPGPATH, XLOGDIR "/%s", dstfname);
3163-
if (rename(tmppath, dstpath) < 0)
3164-
ereport(ERROR,
3165-
(errcode_for_file_access(),
3166-
errmsg("could not rename file \"%s\" to \"%s\": %m",
3167-
tmppath, dstpath)));
3168-
return NULL;
3169-
}
3170-
else
3171-
return pstrdup(tmppath);
3151+
/* install the new file */
3152+
(void) InstallXLogFileSegment(&segno, tmppath, false,
3153+
0, false, ERROR);
31723154
}
31733155

31743156
/*
@@ -3195,14 +3177,16 @@ XLogFileCopy(char *dstfname, char *srcfname, int upto)
31953177
* place. This should be TRUE except during bootstrap log creation. The
31963178
* caller must *not* hold the lock at call.
31973179
*
3180+
* elevel: log level used by this routine.
3181+
*
31983182
* Returns TRUE if the file was installed successfully. FALSE indicates that
31993183
* max_segno limit was exceeded, or an error occurred while renaming the
32003184
* file into place.
32013185
*/
32023186
static bool
32033187
InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
32043188
bool find_free, XLogSegNo max_segno,
3205-
bool use_lock)
3189+
bool use_lock, int elevel)
32063190
{
32073191
char path[MAXPGPATH];
32083192
struct stat stat_buf;
@@ -3247,7 +3231,7 @@ InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
32473231
{
32483232
if (use_lock)
32493233
LWLockRelease(ControlFileLock);
3250-
ereport(LOG,
3234+
ereport(elevel,
32513235
(errcode_for_file_access(),
32523236
errmsg("could not link file \"%s\" to \"%s\" (initialization of log file): %m",
32533237
tmppath, path)));
@@ -3259,7 +3243,7 @@ InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
32593243
{
32603244
if (use_lock)
32613245
LWLockRelease(ControlFileLock);
3262-
ereport(LOG,
3246+
ereport(elevel,
32633247
(errcode_for_file_access(),
32643248
errmsg("could not rename file \"%s\" to \"%s\" (initialization of log file): %m",
32653249
tmppath, path)));
@@ -3748,7 +3732,7 @@ RemoveXlogFile(const char *segname, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
37483732
if (endlogSegNo <= recycleSegNo &&
37493733
lstat(path, &statbuf) == 0 && S_ISREG(statbuf.st_mode) &&
37503734
InstallXLogFileSegment(&endlogSegNo, path,
3751-
true, recycleSegNo, true))
3735+
true, recycleSegNo, true, LOG))
37523736
{
37533737
ereport(DEBUG2,
37543738
(errmsg("recycled transaction log file \"%s\"",
@@ -5227,8 +5211,6 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
52275211
*/
52285212
if (endLogSegNo == startLogSegNo)
52295213
{
5230-
char *tmpfname;
5231-
52325214
XLogFileName(xlogfname, endTLI, endLogSegNo);
52335215

52345216
/*
@@ -5238,9 +5220,7 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
52385220
* considerations. But we should be just as tense as XLogFileInit to
52395221
* avoid emplacing a bogus file.
52405222
*/
5241-
tmpfname = XLogFileCopy(NULL, xlogfname, endOfLog % XLOG_SEG_SIZE);
5242-
if (!InstallXLogFileSegment(&endLogSegNo, tmpfname, false, 0, false))
5243-
elog(ERROR, "InstallXLogFileSegment should not have failed");
5223+
XLogFileCopy(xlogfname, endOfLog % XLOG_SEG_SIZE, endLogSegNo);
52445224
}
52455225
else
52465226
{

0 commit comments

Comments
 (0)