114 #define BootstrapTimeLineID 1
143 bool XLOG_DEBUG =
false;
153 #define NUM_XLOGINSERT_LOCKS 8
176 #ifdef HAVE_FSYNC_WRITETHROUGH
576 #define INSERT_FREESPACE(endptr) \
577 (((endptr) % XLOG_BLCKSZ == 0) ? 0 : (XLOG_BLCKSZ - (endptr) % XLOG_BLCKSZ))
580 #define NextBufIdx(idx) \
581 (((idx) == XLogCtl->XLogCacheBlck) ? 0 : ((idx) + 1))
587 #define XLogRecPtrToBufIdx(recptr) \
588 (((recptr) / XLOG_BLCKSZ) % (XLogCtl->XLogCacheBlck + 1))
593 #define UsableBytesInPage (XLOG_BLCKSZ - SizeOfXLogShortPHD)
599 #define ConvertToXSegs(x, segsize) XLogMBVarToSegs((x), (segsize))
735 bool topxid_included)
742 bool isLogSwitch = (rechdr->
xl_rmid == RM_XLOG_ID &&
754 elog(
ERROR,
"cannot make new WAL entries during recovery");
824 (!prevDoPageWrites ||
855 rdata_crc = rechdr->
xl_crc;
858 rechdr->
xl_crc = rdata_crc;
865 StartPos, EndPos, insertTLI);
907 if (StartPos / XLOG_BLCKSZ != EndPos / XLOG_BLCKSZ)
925 TRACE_POSTGRESQL_WAL_SWITCH();
936 if (StartPos / XLOG_BLCKSZ != EndPos / XLOG_BLCKSZ)
940 if (offset == EndPos % XLOG_BLCKSZ)
956 char *errormsg = NULL;
970 for (; rdata != NULL; rdata = rdata->
next)
993 errormsg ? errormsg :
"no error message");
999 debug_reader->
record = decoded;
1001 debug_reader->
record = NULL;
1048 uint64 startbytepos;
1069 startbytepos =
Insert->CurrBytePos;
1070 endbytepos = startbytepos + size;
1071 prevbytepos =
Insert->PrevBytePos;
1072 Insert->CurrBytePos = endbytepos;
1073 Insert->PrevBytePos = startbytepos;
1103 uint64 startbytepos;
1118 startbytepos =
Insert->CurrBytePos;
1124 *EndPos = *StartPos = ptr;
1128 endbytepos = startbytepos + size;
1129 prevbytepos =
Insert->PrevBytePos;
1141 Insert->CurrBytePos = endbytepos;
1142 Insert->PrevBytePos = startbytepos;
1186 while (rdata != NULL)
1188 char *rdata_data = rdata->
data;
1189 int rdata_len = rdata->
len;
1191 while (rdata_len > freespace)
1197 memcpy(currpos, rdata_data, freespace);
1198 rdata_data += freespace;
1199 rdata_len -= freespace;
1200 written += freespace;
1201 CurrPos += freespace;
1232 memcpy(currpos, rdata_data, rdata_len);
1233 currpos += rdata_len;
1234 CurrPos += rdata_len;
1235 freespace -= rdata_len;
1236 written += rdata_len;
1238 rdata = rdata->
next;
1240 Assert(written == write_len);
1256 CurrPos += freespace;
1264 while (CurrPos < EndPos)
1288 CurrPos += XLOG_BLCKSZ;
1297 if (CurrPos != EndPos)
1298 elog(
PANIC,
"space reserved for WAL record does not match what was written");
1320 static int lockToTry = -1;
1322 if (lockToTry == -1)
1447 elog(
PANIC,
"cannot wait without a PGPROC structure");
1451 bytepos =
Insert->CurrBytePos;
1463 if (upto > reservedUpto)
1466 (
errmsg(
"request to flush past end of generated WAL; request %X/%X, current position %X/%X",
1468 upto = reservedUpto;
1480 finishedUpto = reservedUpto;
1501 insertingat, &insertingat))
1512 }
while (insertingat < upto);
1515 finishedUpto = insertingat;
1517 return finishedUpto;
1541 static uint64 cachedPage = 0;
1542 static char *cachedPos = NULL;
1549 if (ptr / XLOG_BLCKSZ == cachedPage)
1553 return cachedPos + ptr % XLOG_BLCKSZ;
1580 expectedEndPtr = ptr;
1581 expectedEndPtr += XLOG_BLCKSZ - ptr % XLOG_BLCKSZ;
1584 if (expectedEndPtr != endptr)
1609 initializedUpto = ptr;
1616 if (expectedEndPtr != endptr)
1617 elog(
PANIC,
"could not find WAL buffer for %X/%X",
1633 cachedPage = ptr / XLOG_BLCKSZ;
1639 return cachedPos + ptr % XLOG_BLCKSZ;
1667 seg_offset = XLOG_BLCKSZ;
1710 seg_offset = XLOG_BLCKSZ;
1717 seg_offset += fullpages * XLOG_BLCKSZ + bytesleft;
1741 offset = ptr % XLOG_BLCKSZ;
1845 TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_START();
1846 WriteRqst.
Write = OldPageRqstPtr;
1847 WriteRqst.
Flush = 0;
1851 TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE();
1864 NewPageEndPtr = NewPageBeginPtr + XLOG_BLCKSZ;
1874 MemSet((
char *) NewPage, 0, XLOG_BLCKSZ);
1882 NewPage->xlp_tli = tli;
1883 NewPage->xlp_pageaddr = NewPageBeginPtr;
1900 if (
Insert->runningBackups == 0)
1932 if (XLOG_DEBUG && npages > 0)
1934 elog(
DEBUG1,
"initialized %d pages, up to %X/%X",
2021 recycleSegNo = (
XLogSegNo) ceil(((
double) lastredoptr + distance) /
2024 if (recycleSegNo < minSegNo)
2025 recycleSegNo = minSegNo;
2026 if (recycleSegNo > maxSegNo)
2027 recycleSegNo = maxSegNo;
2029 return recycleSegNo;
2069 bool last_iteration;
2114 elog(
PANIC,
"xlog write request %X/%X is past end of log %X/%X",
2169 finishing_seg = !ispartialpage &&
2172 if (last_iteration ||
2184 nbytes = npages * (
Size) XLOG_BLCKSZ;
2229 errmsg(
"could not write to log file %s "
2230 "at offset %u, length %zu: %m",
2231 xlogfname, startoffset, nleft)));
2235 startoffset += written;
2236 }
while (nleft > 0);
2293 if (flexible && npages == 0)
2379 WriteRqstPtr -= WriteRqstPtr % XLOG_BLCKSZ;
2484 if (!force && newMinRecoveryPoint < lsn)
2486 "xlog min recovery request %X/%X is past current point %X/%X",
2499 (
errmsg_internal(
"updated min recovery point to %X/%X on timeline %u",
2501 newMinRecoveryPointTLI)));
2539 elog(
LOG,
"xlog flush request %X/%X; write %X/%X; flush %X/%X",
2556 WriteRqstPtr = record;
2568 if (WriteRqstPtr < XLogCtl->LogwrtRqst.Write)
2636 WriteRqst.
Write = insertpos;
2637 WriteRqst.
Flush = insertpos;
2674 "xlog flush request %X/%X is not satisfied --- flushed only to %X/%X",
2707 bool flexible =
true;
2730 WriteRqst.
Write -= WriteRqst.
Write % XLOG_BLCKSZ;
2792 WriteRqst.
Flush = 0;
2797 elog(
LOG,
"xlog bg flush request write %X/%X; flush: %X/%X, current is write %X/%X; flush %X/%X",
2813 XLogWrite(WriteRqst, insertTLI, flexible);
2923 bool *added,
char *path)
2942 if (errno != ENOENT)
2945 errmsg(
"could not open file \"%s\": %m", path)));
2956 elog(
DEBUG2,
"creating and filling new WAL file");
2967 errmsg(
"could not create file \"%s\": %m", tmppath)));
2999 save_errno = errno ? errno : ENOSPC;
3017 errmsg(
"could not write to file \"%s\": %m", tmppath)));
3028 errmsg(
"could not fsync file \"%s\": %m", tmppath)));
3035 errmsg(
"could not close file \"%s\": %m", tmppath)));
3042 installed_segno = logsegno;
3058 elog(
DEBUG2,
"done creating and filling new WAL file");
3104 errmsg(
"could not open file \"%s\": %m", path)));
3143 errmsg(
"could not open file \"%s\": %m", path)));
3157 errmsg(
"could not create file \"%s\": %m", tmppath)));
3166 nread = upto - nbytes;
3172 if (nread <
sizeof(buffer))
3173 memset(buffer.
data, 0,
sizeof(buffer));
3179 if (nread >
sizeof(buffer))
3180 nread =
sizeof(buffer);
3182 r =
read(srcfd, buffer.
data, nread);
3188 errmsg(
"could not read file \"%s\": %m",
3193 errmsg(
"could not read file \"%s\": read %d of %zu",
3194 path, r, (
Size) nread)));
3200 if ((
int)
write(
fd, buffer.
data,
sizeof(buffer)) != (
int)
sizeof(buffer))
3202 int save_errno = errno;
3209 errno = save_errno ? save_errno : ENOSPC;
3213 errmsg(
"could not write to file \"%s\": %m", tmppath)));
3222 errmsg(
"could not fsync file \"%s\": %m", tmppath)));
3228 errmsg(
"could not close file \"%s\": %m", tmppath)));
3233 errmsg(
"could not close file \"%s\": %m", path)));
3239 elog(
ERROR,
"InstallXLogFileSegment should not have failed");
3273 struct stat stat_buf;
3294 while (
stat(path, &stat_buf) == 0)
3296 if ((*segno) >= max_segno)
3335 errmsg(
"could not open file \"%s\": %m", path)));
3354 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
3356 (void) posix_fadvise(
openLogFile, 0, 0, POSIX_FADV_DONTNEED);
3362 int save_errno = errno;
3368 errmsg(
"could not close file \"%s\": %m", xlogfname)));
3434 int save_errno = errno;
3441 if (segno <= lastRemovedSegNo)
3449 errmsg(
"requested WAL segment %s has already been removed",
3471 return lastRemovedSegNo;
3505 elog(
DEBUG2,
"removing all temporary WAL segments");
3512 if (strncmp(xlde->
d_name,
"xlogtemp.", 9) != 0)
3517 elog(
DEBUG2,
"removed temporary WAL segment \"%s\"", path);
3553 elog(
DEBUG2,
"attempting to remove WAL segments older than log file %s",
3576 if (strcmp(xlde->
d_name + 8, lastoff + 8) <= 0)
3622 recycleSegNo = endLogSegNo + 10;
3629 elog(
DEBUG2,
"attempting to remove WAL segments newer than log file %s",
3645 if (strncmp(xlde->
d_name, switchseg, 8) < 0 &&
3646 strcmp(xlde->
d_name + 8, switchseg + 8) > 0)
3684 const char *segname = segment_de->
d_name;
3694 *endlogSegNo <= recycleSegNo &&
3698 true, recycleSegNo, insertTLI))
3729 if (rename(path, newpath) != 0)
3733 errmsg(
"could not rename file \"%s\": %m",
3769 struct stat stat_buf;
3775 (
errmsg(
"required WAL directory \"%s\" does not exist",
3780 if (
stat(path, &stat_buf) == 0)
3785 (
errmsg(
"required WAL directory \"%s\" does not exist",
3791 (
errmsg(
"creating missing WAL directory \"%s\"", path)));
3794 (
errmsg(
"could not create missing directory \"%s\": %m",
3819 elog(
DEBUG2,
"removing WAL backup history file \"%s\"",
3860 (
errcode(ERRCODE_INTERNAL_ERROR),
3861 errmsg(
"could not generate secret authorization token")));
3932 errmsg(
"could not create file \"%s\": %m",
3944 errmsg(
"could not write to file \"%s\": %m",
3953 errmsg(
"could not fsync file \"%s\": %m",
3960 errmsg(
"could not close file \"%s\": %m",
3969 static char wal_segsz_str[20];
3980 errmsg(
"could not open file \"%s\": %m",
3990 errmsg(
"could not read file \"%s\": %m",
3995 errmsg(
"could not read file \"%s\": read %d of %zu",
4011 (
errmsg(
"database files are incompatible with server"),
4012 errdetail(
"The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x),"
4013 " but the server was compiled with PG_CONTROL_VERSION %d (0x%08x).",
4016 errhint(
"This could be a problem of mismatched byte ordering. It looks like you need to initdb.")));
4020 (
errmsg(
"database files are incompatible with server"),
4021 errdetail(
"The database cluster was initialized with PG_CONTROL_VERSION %d,"
4022 " but the server was compiled with PG_CONTROL_VERSION %d.",
4024 errhint(
"It looks like you need to initdb.")));
4035 (
errmsg(
"incorrect checksum in control file")));
4044 (
errmsg(
"database files are incompatible with server"),
4045 errdetail(
"The database cluster was initialized with CATALOG_VERSION_NO %d,"
4046 " but the server was compiled with CATALOG_VERSION_NO %d.",
4048 errhint(
"It looks like you need to initdb.")));
4051 (
errmsg(
"database files are incompatible with server"),
4052 errdetail(
"The database cluster was initialized with MAXALIGN %d,"
4053 " but the server was compiled with MAXALIGN %d.",
4055 errhint(
"It looks like you need to initdb.")));
4058 (
errmsg(
"database files are incompatible with server"),
4059 errdetail(
"The database cluster appears to use a different floating-point number format than the server executable."),
4060 errhint(
"It looks like you need to initdb.")));
4063 (
errmsg(
"database files are incompatible with server"),
4064 errdetail(
"The database cluster was initialized with BLCKSZ %d,"
4065 " but the server was compiled with BLCKSZ %d.",
4067 errhint(
"It looks like you need to recompile or initdb.")));
4070 (
errmsg(
"database files are incompatible with server"),
4071 errdetail(
"The database cluster was initialized with RELSEG_SIZE %d,"
4072 " but the server was compiled with RELSEG_SIZE %d.",
4074 errhint(
"It looks like you need to recompile or initdb.")));
4077 (
errmsg(
"database files are incompatible with server"),
4078 errdetail(
"The database cluster was initialized with XLOG_BLCKSZ %d,"
4079 " but the server was compiled with XLOG_BLCKSZ %d.",
4081 errhint(
"It looks like you need to recompile or initdb.")));
4084 (
errmsg(
"database files are incompatible with server"),
4085 errdetail(
"The database cluster was initialized with NAMEDATALEN %d,"
4086 " but the server was compiled with NAMEDATALEN %d.",
4088 errhint(
"It looks like you need to recompile or initdb.")));
4091 (
errmsg(
"database files are incompatible with server"),
4092 errdetail(
"The database cluster was initialized with INDEX_MAX_KEYS %d,"
4093 " but the server was compiled with INDEX_MAX_KEYS %d.",
4095 errhint(
"It looks like you need to recompile or initdb.")));
4098 (
errmsg(
"database files are incompatible with server"),
4099 errdetail(
"The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d,"
4100 " but the server was compiled with TOAST_MAX_CHUNK_SIZE %d.",
4102 errhint(
"It looks like you need to recompile or initdb.")));
4105 (
errmsg(
"database files are incompatible with server"),
4106 errdetail(
"The database cluster was initialized with LOBLKSIZE %d,"
4107 " but the server was compiled with LOBLKSIZE %d.",
4109 errhint(
"It looks like you need to recompile or initdb.")));
4111 #ifdef USE_FLOAT8_BYVAL
4114 (
errmsg(
"database files are incompatible with server"),
4115 errdetail(
"The database cluster was initialized without USE_FLOAT8_BYVAL"
4116 " but the server was compiled with USE_FLOAT8_BYVAL."),
4117 errhint(
"It looks like you need to recompile or initdb.")));
4121 (
errmsg(
"database files are incompatible with server"),
4122 errdetail(
"The database cluster was initialized with USE_FLOAT8_BYVAL"
4123 " but the server was compiled without USE_FLOAT8_BYVAL."),
4124 errhint(
"It looks like you need to recompile or initdb.")));
4131 errmsg_plural(
"WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte",
4132 "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes",
4143 errmsg(
"\"min_wal_size\" must be at least twice \"wal_segment_size\"")));
4147 errmsg(
"\"max_wal_size\" must be at least twice \"wal_segment_size\"")));
4219 return nextUnloggedLSN;
4308 foreach(l, elemlist)
4310 char *tok = (
char *)
lfirst(l);
4316 for (rmid = 0; rmid <=
RM_MAX_ID; rmid++)
4318 newwalconsistency[rmid] =
true;
4325 for (rmid = 0; rmid <=
RM_MAX_ID; rmid++)
4330 newwalconsistency[rmid] =
true;
4362 memcpy(*extra, newwalconsistency, (
RM_MAX_ID + 1) *
sizeof(
bool));
4428 return "(disabled)";
4507 size =
add_size(size, XLOG_BLCKSZ);
4536 if (walDebugCxt == NULL)
4553 if (foundCFile || foundXLog)
4556 Assert(foundCFile && foundXLog);
4561 if (localControlFile)
4562 pfree(localControlFile);
4571 if (localControlFile)
4574 pfree(localControlFile);
4607 allocptr = (
char *)
TYPEALIGN(XLOG_BLCKSZ, allocptr);
4638 uint64 sysidentifier;
4658 sysidentifier = ((uint64) tv.tv_sec) << 32;
4659 sysidentifier |= ((uint64) tv.tv_usec) << 12;
4660 sysidentifier |= getpid() & 0xFFF;
4663 buffer = (
char *)
palloc(XLOG_BLCKSZ + XLOG_BLCKSZ);
4665 memset(page, 0, XLOG_BLCKSZ);
4722 *(recptr++) =
sizeof(checkPoint);
4723 memcpy(recptr, &checkPoint,
sizeof(checkPoint));
4724 recptr +=
sizeof(checkPoint);
4752 errmsg(
"could not write bootstrap write-ahead log file: %m")));
4760 errmsg(
"could not fsync bootstrap write-ahead log file: %m")));
4766 errmsg(
"could not close bootstrap write-ahead log file: %m")));
4797 static char buf[128];
4800 "%Y-%m-%d %H:%M:%S %Z",
4817 Assert(endTLI != newTLI);
4839 if (endLogSegNo == startLogSegNo)
4863 int save_errno = errno;
4869 errmsg(
"could not close file \"%s\": %m", xlogfname)));
4893 "recovery_end_command",
4983 (
errmsg(
"WAL was generated with wal_level=minimal, cannot continue recovering"),
4984 errdetail(
"This happens if you temporarily set wal_level=minimal on the server."),
4985 errhint(
"Use a backup taken after setting wal_level to higher than minimal.")));
5024 bool haveBackupLabel;
5028 bool performedWalRecovery;
5033 bool promoted =
false;
5049 (
errmsg(
"control file contains invalid checkpoint location")));
5060 (
errmsg(
"database system was shut down at %s",
5066 (
errmsg(
"database system was shut down in recovery at %s",
5072 (
errmsg(
"database system shutdown was interrupted; last known up at %s",
5078 (
errmsg(
"database system was interrupted while in recovery at %s",
5080 errhint(
"This probably means that some data is corrupted and"
5081 " you will have to use the last backup for recovery.")));
5086 (
errmsg(
"database system was interrupted while in recovery at log time %s",
5088 errhint(
"If this has occurred more than once some data might be corrupted"
5089 " and you might need to choose an earlier recovery target.")));
5094 (
errmsg(
"database system was interrupted; last known up at %s",
5100 (
errmsg(
"control file contains invalid database cluster state")));
5104 #ifdef XLOG_REPLAY_DELAY
5154 &haveBackupLabel, &haveTblspcMap);
5305 if (haveBackupLabel)
5411 running.
xcnt = nxids;
5420 running.
xids = xids;
5432 performedWalRecovery =
true;
5435 performedWalRecovery =
false;
5441 EndOfLog = endOfRecoveryInfo->
endOfLog;
5484 (
errmsg(
"WAL ends before end of online backup"),
5485 errhint(
"All WAL generated while online backup was taken must be available at recovery.")));
5488 (
errmsg(
"WAL ends before consistent recovery point")));
5534 (
errmsg(
"selected new timeline ID: %u", newTLI)));
5567 (
errmsg(
"archive recovery complete")));
5608 if (EndOfLog % XLOG_BLCKSZ != 0)