111#define BootstrapTimeLineID 1
140bool XLOG_DEBUG =
false;
150#define NUM_XLOGINSERT_LOCKS 8
173#ifdef HAVE_FSYNC_WRITETHROUGH
580#define INSERT_FREESPACE(endptr) \
581 (((endptr) % XLOG_BLCKSZ == 0) ? 0 : (XLOG_BLCKSZ - (endptr) % XLOG_BLCKSZ))
584#define NextBufIdx(idx) \
585 (((idx) == XLogCtl->XLogCacheBlck) ? 0 : ((idx) + 1))
591#define XLogRecPtrToBufIdx(recptr) \
592 (((recptr) / XLOG_BLCKSZ) % (XLogCtl->XLogCacheBlck + 1))
597#define UsableBytesInPage (XLOG_BLCKSZ - SizeOfXLogShortPHD)
603#define ConvertToXSegs(x, segsize) XLogMBVarToSegs((x), (segsize))
620#define RefreshXLogWriteResult(_target) \
622 _target.Flush = pg_atomic_read_u64(&XLogCtl->logFlushResult); \
624 _target.Write = pg_atomic_read_u64(&XLogCtl->logWriteResult); \
752 bool topxid_included)
779 elog(
ERROR,
"cannot make new WAL entries during recovery");
849 (!prevDoPageWrites ||
913 rdata_crc = rechdr->
xl_crc;
916 rechdr->
xl_crc = rdata_crc;
924 StartPos, EndPos, insertTLI);
966 if (StartPos / XLOG_BLCKSZ != EndPos / XLOG_BLCKSZ)
983 TRACE_POSTGRESQL_WAL_SWITCH();
994 if (StartPos / XLOG_BLCKSZ != EndPos / XLOG_BLCKSZ)
998 if (offset == EndPos % XLOG_BLCKSZ)
1014 char *errormsg = NULL;
1028 for (; rdata != NULL; rdata = rdata->
next)
1039 .segment_open = NULL,
1040 .segment_close = NULL),
1053 errormsg ? errormsg :
"no error message");
1059 debug_reader->
record = decoded;
1061 debug_reader->
record = NULL;
1133 startbytepos =
Insert->CurrBytePos;
1134 endbytepos = startbytepos +
size;
1135 prevbytepos =
Insert->PrevBytePos;
1136 Insert->CurrBytePos = endbytepos;
1137 Insert->PrevBytePos = startbytepos;
1182 startbytepos =
Insert->CurrBytePos;
1188 *EndPos = *StartPos = ptr;
1192 endbytepos = startbytepos +
size;
1193 prevbytepos =
Insert->PrevBytePos;
1205 Insert->CurrBytePos = endbytepos;
1206 Insert->PrevBytePos = startbytepos;
1250 while (rdata != NULL)
1252 const char *rdata_data = rdata->
data;
1253 int rdata_len = rdata->
len;
1255 while (rdata_len > freespace)
1261 memcpy(currpos, rdata_data, freespace);
1262 rdata_data += freespace;
1263 rdata_len -= freespace;
1264 written += freespace;
1265 CurrPos += freespace;
1296 memcpy(currpos, rdata_data, rdata_len);
1297 currpos += rdata_len;
1298 CurrPos += rdata_len;
1299 freespace -= rdata_len;
1300 written += rdata_len;
1302 rdata = rdata->
next;
1304 Assert(written == write_len);
1320 CurrPos += freespace;
1328 while (CurrPos < EndPos)
1352 CurrPos += XLOG_BLCKSZ;
1361 if (CurrPos != EndPos)
1364 errmsg_internal(
"space reserved for WAL record does not match what was written"));
1386 static int lockToTry = -1;
1388 if (lockToTry == -1)
1514 elog(
PANIC,
"cannot wait without a PGPROC structure");
1521 if (upto <= inserted)
1526 bytepos =
Insert->CurrBytePos;
1538 if (upto > reservedUpto)
1541 (
errmsg(
"request to flush past end of generated WAL; request %X/%X, current position %X/%X",
1543 upto = reservedUpto;
1555 finishedUpto = reservedUpto;
1587 insertingat, &insertingat))
1598 }
while (insertingat < upto);
1601 finishedUpto = insertingat;
1612 return finishedUpto;
1636 static uint64 cachedPage = 0;
1637 static char *cachedPos = NULL;
1644 if (ptr / XLOG_BLCKSZ == cachedPage)
1648 return cachedPos + ptr % XLOG_BLCKSZ;
1671 expectedEndPtr = ptr;
1672 expectedEndPtr += XLOG_BLCKSZ - ptr % XLOG_BLCKSZ;
1675 if (expectedEndPtr != endptr)
1700 initializedUpto = ptr;
1707 if (expectedEndPtr != endptr)
1708 elog(
PANIC,
"could not find WAL buffer for %X/%X",
1724 cachedPage = ptr / XLOG_BLCKSZ;
1730 return cachedPos + ptr % XLOG_BLCKSZ;
1751 char *pdst = dstbuf;
1754 Size nbytes = count;
1766 if (startptr + count > inserted)
1768 errmsg(
"cannot read past end of generated WAL: requested %X/%X, current position %X/%X",
1788 uint32 offset = recptr % XLOG_BLCKSZ;
1800 expectedEndPtr = recptr + (XLOG_BLCKSZ - offset);
1807 if (expectedEndPtr != endptr)
1816 psrc = page + offset;
1817 npagebytes =
Min(nbytes, XLOG_BLCKSZ - offset);
1826 memcpy(pdst, psrc, npagebytes);
1839 if (expectedEndPtr != endptr)
1843 recptr += npagebytes;
1844 nbytes -= npagebytes;
1847 Assert(pdst - dstbuf <= count);
1849 return pdst - dstbuf;
1877 seg_offset = XLOG_BLCKSZ;
1920 seg_offset = XLOG_BLCKSZ;
1927 seg_offset += fullpages * XLOG_BLCKSZ + bytesleft;
1951 offset = ptr % XLOG_BLCKSZ;
2055 TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_START();
2056 WriteRqst.
Write = OldPageRqstPtr;
2057 WriteRqst.
Flush = 0;
2061 TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE();
2074 NewPageEndPtr = NewPageBeginPtr + XLOG_BLCKSZ;
2092 MemSet((
char *) NewPage, 0, XLOG_BLCKSZ);
2100 NewPage->xlp_tli = tli;
2101 NewPage->xlp_pageaddr = NewPageBeginPtr;
2118 if (
Insert->runningBackups == 0)
2149 if (XLOG_DEBUG && npages > 0)
2151 elog(
DEBUG1,
"initialized %d pages, up to %X/%X",
2209 GUC_check_errdetail(
"The WAL segment size must be a power of two between 1 MB and 1 GB.");
2228 "max_slot_wal_keep_size");
2269 recycleSegNo = (
XLogSegNo) ceil(((
double) lastredoptr + distance) /
2272 if (recycleSegNo < minSegNo)
2273 recycleSegNo = minSegNo;
2274 if (recycleSegNo > maxSegNo)
2275 recycleSegNo = maxSegNo;
2277 return recycleSegNo;
2317 bool last_iteration;
2362 elog(
PANIC,
"xlog write request %X/%X is past end of log %X/%X",
2417 finishing_seg = !ispartialpage &&
2420 if (last_iteration ||
2432 nbytes = npages * (
Size) XLOG_BLCKSZ;
2479 errmsg(
"could not write to log file \"%s\" at offset %u, length %zu: %m",
2480 xlogfname, startoffset, nleft)));
2484 startoffset += written;
2485 }
while (nleft > 0);
2542 if (flexible && npages == 0)
2607#ifdef USE_ASSERT_CHECKING
2652 if (asyncXactLSN <= prevAsyncXactLSN)
2775 if (!force && newMinRecoveryPoint < lsn)
2777 "xlog min recovery request %X/%X is past current point %X/%X",
2790 (
errmsg_internal(
"updated min recovery point to %X/%X on timeline %u",
2792 newMinRecoveryPointTLI)));
2830 elog(
LOG,
"xlog flush request %X/%X; write %X/%X; flush %X/%X",
2847 WriteRqstPtr = record;
2867 if (WriteRqstPtr < XLogCtl->LogwrtRqst.Write)
2925 WriteRqst.
Write = insertpos;
2926 WriteRqst.
Flush = insertpos;
2963 "xlog flush request %X/%X is not satisfied --- flushed only to %X/%X",
2996 bool flexible =
true;
3018 WriteRqst.
Write -= WriteRqst.
Write % XLOG_BLCKSZ;
3085 WriteRqst.
Flush = 0;
3090 elog(
LOG,
"xlog bg flush request write %X/%X; flush: %X/%X, current is write %X/%X; flush %X/%X",
3106 XLogWrite(WriteRqst, insertTLI, flexible);
3214 bool *added,
char *path)
3221 int open_flags = O_RDWR | O_CREAT | O_EXCL |
PG_BINARY;
3236 if (errno != ENOENT)
3239 errmsg(
"could not open file \"%s\": %m", path)));
3250 elog(
DEBUG2,
"creating and filling new WAL file");
3264 errmsg(
"could not create file \"%s\": %m", tmppath)));
3299 save_errno = errno ? errno : ENOSPC;
3325 errmsg(
"could not write to file \"%s\": %m", tmppath)));
3339 errmsg(
"could not fsync file \"%s\": %m", tmppath)));
3349 errmsg(
"could not close file \"%s\": %m", tmppath)));
3356 installed_segno = logsegno;
3372 elog(
DEBUG2,
"done creating and filling new WAL file");
3419 errmsg(
"could not open file \"%s\": %m", path)));
3458 errmsg(
"could not open file \"%s\": %m", path)));
3472 errmsg(
"could not create file \"%s\": %m", tmppath)));
3481 nread = upto - nbytes;
3487 if (nread <
sizeof(buffer))
3488 memset(buffer.
data, 0,
sizeof(buffer));
3494 if (nread >
sizeof(buffer))
3495 nread =
sizeof(buffer);
3497 r =
read(srcfd, buffer.
data, nread);
3503 errmsg(
"could not read file \"%s\": %m",
3508 errmsg(
"could not read file \"%s\": read %d of %zu",
3509 path, r, (
Size) nread)));
3515 if ((
int)
write(
fd, buffer.
data,
sizeof(buffer)) != (
int)
sizeof(buffer))
3517 int save_errno = errno;
3524 errno = save_errno ? save_errno : ENOSPC;
3528 errmsg(
"could not write to file \"%s\": %m", tmppath)));
3537 errmsg(
"could not fsync file \"%s\": %m", tmppath)));
3543 errmsg(
"could not close file \"%s\": %m", tmppath)));
3548 errmsg(
"could not close file \"%s\": %m", path)));
3554 elog(
ERROR,
"InstallXLogFileSegment should not have failed");
3588 struct stat stat_buf;
3609 while (
stat(path, &stat_buf) == 0)
3611 if ((*segno) >= max_segno)
3651 errmsg(
"could not open file \"%s\": %m", path)));
3670#if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
3672 (void) posix_fadvise(
openLogFile, 0, 0, POSIX_FADV_DONTNEED);
3678 int save_errno = errno;
3684 errmsg(
"could not close file \"%s\": %m", xlogfname)));
3750 int save_errno = errno;
3757 if (segno <= lastRemovedSegNo)
3765 errmsg(
"requested WAL segment %s has already been removed",
3787 return lastRemovedSegNo;
3816 if (tli != file_tli)
3820 if (oldest_segno == 0 || file_segno < oldest_segno)
3821 oldest_segno = file_segno;
3825 return oldest_segno;
3858 elog(
DEBUG2,
"removing all temporary WAL segments");
3865 if (strncmp(xlde->
d_name,
"xlogtemp.", 9) != 0)
3870 elog(
DEBUG2,
"removed temporary WAL segment \"%s\"", path);
3906 elog(
DEBUG2,
"attempting to remove WAL segments older than log file %s",
3929 if (strcmp(xlde->
d_name + 8, lastoff + 8) <= 0)
3976 recycleSegNo = endLogSegNo + 10;
3983 elog(
DEBUG2,
"attempting to remove WAL segments newer than log file %s",
3999 if (strncmp(xlde->
d_name, switchseg, 8) < 0 &&
4000 strcmp(xlde->
d_name + 8, switchseg + 8) > 0)
4038 const char *segname = segment_de->
d_name;
4048 *endlogSegNo <= recycleSegNo &&
4052 true, recycleSegNo, insertTLI))
4083 if (rename(path, newpath) != 0)
4087 errmsg(
"could not rename file \"%s\": %m",
4123 struct stat stat_buf;
4130 errmsg(
"required WAL directory \"%s\" does not exist",
4135 if (
stat(path, &stat_buf) == 0)
4141 errmsg(
"required WAL directory \"%s\" does not exist",
4147 (
errmsg(
"creating missing WAL directory \"%s\"", path)));
4151 errmsg(
"could not create missing directory \"%s\": %m",
4157 if (
stat(path, &stat_buf) == 0)
4162 (
errmsg(
"required WAL directory \"%s\" does not exist",
4168 (
errmsg(
"creating missing WAL directory \"%s\"", path)));
4171 (
errmsg(
"could not create missing directory \"%s\": %m",
4196 elog(
DEBUG2,
"removing WAL backup history file \"%s\"",
4237 (
errcode(ERRCODE_INTERNAL_ERROR),
4238 errmsg(
"could not generate secret authorization token")));
4309 errmsg(
"could not create file \"%s\": %m",
4321 errmsg(
"could not write to file \"%s\": %m",
4330 errmsg(
"could not fsync file \"%s\": %m",
4337 errmsg(
"could not close file \"%s\": %m",
4346 char wal_segsz_str[20];
4357 errmsg(
"could not open file \"%s\": %m",
4367 errmsg(
"could not read file \"%s\": %m",
4372 errmsg(
"could not read file \"%s\": read %d of %zu",
4388 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4389 errmsg(
"database files are incompatible with server"),
4390 errdetail(
"The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x),"
4391 " but the server was compiled with PG_CONTROL_VERSION %d (0x%08x).",
4394 errhint(
"This could be a problem of mismatched byte ordering. It looks like you need to initdb.")));
4398 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4399 errmsg(
"database files are incompatible with server"),
4400 errdetail(
"The database cluster was initialized with PG_CONTROL_VERSION %d,"
4401 " but the server was compiled with PG_CONTROL_VERSION %d.",
4403 errhint(
"It looks like you need to initdb.")));
4414 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4415 errmsg(
"incorrect checksum in control file")));
4424 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4425 errmsg(
"database files are incompatible with server"),
4427 errdetail(
"The database cluster was initialized with %s %d,"
4428 " but the server was compiled with %s %d.",
4431 errhint(
"It looks like you need to initdb.")));
4434 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4435 errmsg(
"database files are incompatible with server"),
4437 errdetail(
"The database cluster was initialized with %s %d,"
4438 " but the server was compiled with %s %d.",
4440 "MAXALIGN", MAXIMUM_ALIGNOF),
4441 errhint(
"It looks like you need to initdb.")));
4444 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4445 errmsg(
"database files are incompatible with server"),
4446 errdetail(
"The database cluster appears to use a different floating-point number format than the server executable."),
4447 errhint(
"It looks like you need to initdb.")));
4450 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4451 errmsg(
"database files are incompatible with server"),
4453 errdetail(
"The database cluster was initialized with %s %d,"
4454 " but the server was compiled with %s %d.",
4457 errhint(
"It looks like you need to recompile or initdb.")));
4460 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4461 errmsg(
"database files are incompatible with server"),
4463 errdetail(
"The database cluster was initialized with %s %d,"
4464 " but the server was compiled with %s %d.",
4466 "RELSEG_SIZE", RELSEG_SIZE),
4467 errhint(
"It looks like you need to recompile or initdb.")));
4470 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4471 errmsg(
"database files are incompatible with server"),
4473 errdetail(
"The database cluster was initialized with %s %d,"
4474 " but the server was compiled with %s %d.",
4476 "XLOG_BLCKSZ", XLOG_BLCKSZ),
4477 errhint(
"It looks like you need to recompile or initdb.")));
4480 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4481 errmsg(
"database files are incompatible with server"),
4483 errdetail(
"The database cluster was initialized with %s %d,"
4484 " but the server was compiled with %s %d.",
4487 errhint(
"It looks like you need to recompile or initdb.")));
4490 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4491 errmsg(
"database files are incompatible with server"),
4493 errdetail(
"The database cluster was initialized with %s %d,"
4494 " but the server was compiled with %s %d.",
4497 errhint(
"It looks like you need to recompile or initdb.")));
4500 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4501 errmsg(
"database files are incompatible with server"),
4503 errdetail(
"The database cluster was initialized with %s %d,"
4504 " but the server was compiled with %s %d.",
4507 errhint(
"It looks like you need to recompile or initdb.")));
4510 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4511 errmsg(
"database files are incompatible with server"),
4513 errdetail(
"The database cluster was initialized with %s %d,"
4514 " but the server was compiled with %s %d.",
4517 errhint(
"It looks like you need to recompile or initdb.")));
4519#ifdef USE_FLOAT8_BYVAL
4522 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4523 errmsg(
"database files are incompatible with server"),
4524 errdetail(
"The database cluster was initialized without USE_FLOAT8_BYVAL"
4525 " but the server was compiled with USE_FLOAT8_BYVAL."),
4526 errhint(
"It looks like you need to recompile or initdb.")));
4530 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
4531 errmsg(
"database files are incompatible with server"),
4532 errdetail(
"The database cluster was initialized with USE_FLOAT8_BYVAL"
4533 " but the server was compiled without USE_FLOAT8_BYVAL."),
4534 errhint(
"It looks like you need to recompile or initdb.")));
4541 errmsg_plural(
"invalid WAL segment size in control file (%d byte)",
4542 "invalid WAL segment size in control file (%d bytes)",
4545 errdetail(
"The WAL segment size must be a power of two between 1 MB and 1 GB.")));
4555 errmsg(
"\"%s\" must be at least twice \"%s\"",
4556 "min_wal_size",
"wal_segment_size")));
4561 errmsg(
"\"%s\" must be at least twice \"%s\"",
4562 "max_wal_size",
"wal_segment_size")));
4716 foreach(l, elemlist)
4718 char *tok = (
char *)
lfirst(l);
4724 for (rmid = 0; rmid <=
RM_MAX_ID; rmid++)
4726 newwalconsistency[rmid] =
true;
4733 for (rmid = 0; rmid <=
RM_MAX_ID; rmid++)
4738 newwalconsistency[rmid] =
true;
4770 memcpy(*extra, newwalconsistency, (
RM_MAX_ID + 1) *
sizeof(
bool));
4836 return "(disabled)";
4954 if (walDebugCxt == NULL)
4971 if (foundCFile || foundXLog)
4974 Assert(foundCFile && foundXLog);
4979 if (localControlFile)
4980 pfree(localControlFile);
4989 if (localControlFile)
4992 pfree(localControlFile);
5028 allocptr = (
char *)
TYPEALIGN(XLOG_BLCKSZ, allocptr);
5082 sysidentifier = ((
uint64) tv.tv_sec) << 32;
5083 sysidentifier |= ((
uint64) tv.tv_usec) << 12;
5084 sysidentifier |= getpid() & 0xFFF;
5087 buffer = (
char *)
palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
5089 memset(page, 0, XLOG_BLCKSZ);
5147 *(recptr++) =
sizeof(checkPoint);
5148 memcpy(recptr, &checkPoint,
sizeof(checkPoint));
5149 recptr +=
sizeof(checkPoint);
5177 errmsg(
"could not write bootstrap write-ahead log file: %m")));
5185 errmsg(
"could not fsync bootstrap write-ahead log file: %m")));
5191 errmsg(
"could not close bootstrap write-ahead log file: %m")));
5225 "%Y-%m-%d %H:%M:%S %Z",
5242 Assert(endTLI != newTLI);