| 1 | /* |
| 2 | * xlog_internal.h |
| 3 | * |
| 4 | * PostgreSQL write-ahead log internal declarations |
| 5 | * |
| 6 | * NOTE: this file is intended to contain declarations useful for |
| 7 | * manipulating the XLOG files directly, but it is not supposed to be |
| 8 | * needed by rmgr routines (redo support for individual record types). |
| 9 | * So the XLogRecord typedef and associated stuff appear in xlogrecord.h. |
| 10 | * |
| 11 | * Note: This file must be includable in both frontend and backend contexts, |
| 12 | * to allow stand-alone tools like pg_receivewal to deal with WAL files. |
| 13 | * |
| 14 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 15 | * Portions Copyright (c) 1994, Regents of the University of California |
| 16 | * |
| 17 | * src/include/access/xlog_internal.h |
| 18 | */ |
| 19 | #ifndef XLOG_INTERNAL_H |
| 20 | #define XLOG_INTERNAL_H |
| 21 | |
| 22 | #include "access/xlogdefs.h" |
| 23 | #include "access/xlogreader.h" |
| 24 | #include "datatype/timestamp.h" |
| 25 | #include "lib/stringinfo.h" |
| 26 | #include "pgtime.h" |
| 27 | #include "storage/block.h" |
| 28 | #include "storage/relfilenode.h" |
| 29 | |
| 30 | |
| 31 | /* |
| 32 | * Each page of XLOG file has a header like this: |
| 33 | */ |
| 34 | #define XLOG_PAGE_MAGIC 0xD101 /* can be used as WAL version indicator */ |
| 35 | |
| 36 | typedef struct |
| 37 | { |
| 38 | uint16 ; /* magic value for correctness checks */ |
| 39 | uint16 ; /* flag bits, see below */ |
| 40 | TimeLineID ; /* TimeLineID of first record on page */ |
| 41 | XLogRecPtr ; /* XLOG address of this page */ |
| 42 | |
| 43 | /* |
| 44 | * When there is not enough space on current page for whole record, we |
| 45 | * continue on the next page. xlp_rem_len is the number of bytes |
| 46 | * remaining from a previous page. |
| 47 | * |
| 48 | * Note that xl_rem_len includes backup-block data; that is, it tracks |
| 49 | * xl_tot_len not xl_len in the initial header. Also note that the |
| 50 | * continuation data isn't necessarily aligned. |
| 51 | */ |
| 52 | uint32 ; /* total len of remaining data for record */ |
| 53 | } ; |
| 54 | |
| 55 | #define SizeOfXLogShortPHD MAXALIGN(sizeof(XLogPageHeaderData)) |
| 56 | |
| 57 | typedef XLogPageHeaderData *; |
| 58 | |
| 59 | /* |
| 60 | * When the XLP_LONG_HEADER flag is set, we store additional fields in the |
| 61 | * page header. (This is ordinarily done just in the first page of an |
| 62 | * XLOG file.) The additional fields serve to identify the file accurately. |
| 63 | */ |
| 64 | typedef struct |
| 65 | { |
| 66 | XLogPageHeaderData ; /* standard header fields */ |
| 67 | uint64 ; /* system identifier from pg_control */ |
| 68 | uint32 ; /* just as a cross-check */ |
| 69 | uint32 ; /* just as a cross-check */ |
| 70 | } ; |
| 71 | |
| 72 | #define SizeOfXLogLongPHD MAXALIGN(sizeof(XLogLongPageHeaderData)) |
| 73 | |
| 74 | typedef XLogLongPageHeaderData *; |
| 75 | |
| 76 | /* When record crosses page boundary, set this flag in new page's header */ |
| 77 | #define XLP_FIRST_IS_CONTRECORD 0x0001 |
| 78 | /* This flag indicates a "long" page header */ |
| 79 | #define 0x0002 |
| 80 | /* This flag indicates backup blocks starting in this page are optional */ |
| 81 | #define XLP_BKP_REMOVABLE 0x0004 |
| 82 | /* All defined flag bits in xlp_info (used for validity checking of header) */ |
| 83 | #define XLP_ALL_FLAGS 0x0007 |
| 84 | |
| 85 | #define (hdr) \ |
| 86 | (((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD) |
| 87 | |
| 88 | /* wal_segment_size can range from 1MB to 1GB */ |
| 89 | #define WalSegMinSize 1024 * 1024 |
| 90 | #define WalSegMaxSize 1024 * 1024 * 1024 |
| 91 | /* default number of min and max wal segments */ |
| 92 | #define DEFAULT_MIN_WAL_SEGS 5 |
| 93 | #define DEFAULT_MAX_WAL_SEGS 64 |
| 94 | |
| 95 | /* check that the given size is a valid wal_segment_size */ |
| 96 | #define IsPowerOf2(x) (x > 0 && ((x) & ((x)-1)) == 0) |
| 97 | #define IsValidWalSegSize(size) \ |
| 98 | (IsPowerOf2(size) && \ |
| 99 | ((size) >= WalSegMinSize && (size) <= WalSegMaxSize)) |
| 100 | |
| 101 | #define XLogSegmentsPerXLogId(wal_segsz_bytes) \ |
| 102 | (UINT64CONST(0x100000000) / (wal_segsz_bytes)) |
| 103 | |
| 104 | #define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest) \ |
| 105 | (dest) = (segno) * (wal_segsz_bytes) + (offset) |
| 106 | |
| 107 | #define XLogSegmentOffset(xlogptr, wal_segsz_bytes) \ |
| 108 | ((xlogptr) & ((wal_segsz_bytes) - 1)) |
| 109 | |
| 110 | /* |
| 111 | * Compute a segment number from an XLogRecPtr. |
| 112 | * |
| 113 | * For XLByteToSeg, do the computation at face value. For XLByteToPrevSeg, |
| 114 | * a boundary byte is taken to be in the previous segment. This is suitable |
| 115 | * for deciding which segment to write given a pointer to a record end, |
| 116 | * for example. |
| 117 | */ |
| 118 | #define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes) \ |
| 119 | logSegNo = (xlrp) / (wal_segsz_bytes) |
| 120 | |
| 121 | #define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \ |
| 122 | logSegNo = ((xlrp) - 1) / (wal_segsz_bytes) |
| 123 | |
| 124 | /* |
| 125 | * Is an XLogRecPtr within a particular XLOG segment? |
| 126 | * |
| 127 | * For XLByteInSeg, do the computation at face value. For XLByteInPrevSeg, |
| 128 | * a boundary byte is taken to be in the previous segment. |
| 129 | */ |
| 130 | #define XLByteInSeg(xlrp, logSegNo, wal_segsz_bytes) \ |
| 131 | (((xlrp) / (wal_segsz_bytes)) == (logSegNo)) |
| 132 | |
| 133 | #define XLByteInPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \ |
| 134 | ((((xlrp) - 1) / (wal_segsz_bytes)) == (logSegNo)) |
| 135 | |
| 136 | /* Check if an XLogRecPtr value is in a plausible range */ |
| 137 | #define XRecOffIsValid(xlrp) \ |
| 138 | ((xlrp) % XLOG_BLCKSZ >= SizeOfXLogShortPHD) |
| 139 | |
| 140 | /* |
| 141 | * The XLog directory and control file (relative to $PGDATA) |
| 142 | */ |
| 143 | #define XLOGDIR "pg_wal" |
| 144 | #define XLOG_CONTROL_FILE "global/pg_control" |
| 145 | |
| 146 | /* |
| 147 | * These macros encapsulate knowledge about the exact layout of XLog file |
| 148 | * names, timeline history file names, and archive-status file names. |
| 149 | */ |
| 150 | #define MAXFNAMELEN 64 |
| 151 | |
| 152 | /* Length of XLog file name */ |
| 153 | #define XLOG_FNAME_LEN 24 |
| 154 | |
| 155 | #define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes) \ |
| 156 | snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, \ |
| 157 | (uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \ |
| 158 | (uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes))) |
| 159 | |
| 160 | #define XLogFileNameById(fname, tli, log, seg) \ |
| 161 | snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, log, seg) |
| 162 | |
| 163 | #define IsXLogFileName(fname) \ |
| 164 | (strlen(fname) == XLOG_FNAME_LEN && \ |
| 165 | strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN) |
| 166 | |
| 167 | /* |
| 168 | * XLOG segment with .partial suffix. Used by pg_receivewal and at end of |
| 169 | * archive recovery, when we want to archive a WAL segment but it might not |
| 170 | * be complete yet. |
| 171 | */ |
| 172 | #define IsPartialXLogFileName(fname) \ |
| 173 | (strlen(fname) == XLOG_FNAME_LEN + strlen(".partial") && \ |
| 174 | strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN && \ |
| 175 | strcmp((fname) + XLOG_FNAME_LEN, ".partial") == 0) |
| 176 | |
| 177 | #define XLogFromFileName(fname, tli, logSegNo, wal_segsz_bytes) \ |
| 178 | do { \ |
| 179 | uint32 log; \ |
| 180 | uint32 seg; \ |
| 181 | sscanf(fname, "%08X%08X%08X", tli, &log, &seg); \ |
| 182 | *logSegNo = (uint64) log * XLogSegmentsPerXLogId(wal_segsz_bytes) + seg; \ |
| 183 | } while (0) |
| 184 | |
| 185 | #define XLogFilePath(path, tli, logSegNo, wal_segsz_bytes) \ |
| 186 | snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli, \ |
| 187 | (uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \ |
| 188 | (uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes))) |
| 189 | |
| 190 | #define TLHistoryFileName(fname, tli) \ |
| 191 | snprintf(fname, MAXFNAMELEN, "%08X.history", tli) |
| 192 | |
| 193 | #define IsTLHistoryFileName(fname) \ |
| 194 | (strlen(fname) == 8 + strlen(".history") && \ |
| 195 | strspn(fname, "0123456789ABCDEF") == 8 && \ |
| 196 | strcmp((fname) + 8, ".history") == 0) |
| 197 | |
| 198 | #define TLHistoryFilePath(path, tli) \ |
| 199 | snprintf(path, MAXPGPATH, XLOGDIR "/%08X.history", tli) |
| 200 | |
| 201 | #define StatusFilePath(path, xlog, suffix) \ |
| 202 | snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix) |
| 203 | |
| 204 | #define BackupHistoryFileName(fname, tli, logSegNo, startpoint, wal_segsz_bytes) \ |
| 205 | snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli, \ |
| 206 | (uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \ |
| 207 | (uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes)), \ |
| 208 | (uint32) (XLogSegmentOffset(startpoint, wal_segsz_bytes))) |
| 209 | |
| 210 | #define IsBackupHistoryFileName(fname) \ |
| 211 | (strlen(fname) > XLOG_FNAME_LEN && \ |
| 212 | strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN && \ |
| 213 | strcmp((fname) + strlen(fname) - strlen(".backup"), ".backup") == 0) |
| 214 | |
| 215 | #define BackupHistoryFilePath(path, tli, logSegNo, startpoint, wal_segsz_bytes) \ |
| 216 | snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli, \ |
| 217 | (uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \ |
| 218 | (uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes)), \ |
| 219 | (uint32) (XLogSegmentOffset((startpoint), wal_segsz_bytes))) |
| 220 | |
| 221 | /* |
| 222 | * Information logged when we detect a change in one of the parameters |
| 223 | * important for Hot Standby. |
| 224 | */ |
| 225 | typedef struct xl_parameter_change |
| 226 | { |
| 227 | int MaxConnections; |
| 228 | int max_worker_processes; |
| 229 | int max_wal_senders; |
| 230 | int max_prepared_xacts; |
| 231 | int max_locks_per_xact; |
| 232 | int wal_level; |
| 233 | bool wal_log_hints; |
| 234 | bool track_commit_timestamp; |
| 235 | } xl_parameter_change; |
| 236 | |
| 237 | /* logs restore point */ |
| 238 | typedef struct xl_restore_point |
| 239 | { |
| 240 | TimestampTz rp_time; |
| 241 | char rp_name[MAXFNAMELEN]; |
| 242 | } xl_restore_point; |
| 243 | |
| 244 | /* End of recovery mark, when we don't do an END_OF_RECOVERY checkpoint */ |
| 245 | typedef struct xl_end_of_recovery |
| 246 | { |
| 247 | TimestampTz end_time; |
| 248 | TimeLineID ThisTimeLineID; /* new TLI */ |
| 249 | TimeLineID PrevTimeLineID; /* previous TLI we forked off from */ |
| 250 | } xl_end_of_recovery; |
| 251 | |
| 252 | /* |
| 253 | * The functions in xloginsert.c construct a chain of XLogRecData structs |
| 254 | * to represent the final WAL record. |
| 255 | */ |
| 256 | typedef struct XLogRecData |
| 257 | { |
| 258 | struct XLogRecData *next; /* next struct in chain, or NULL */ |
| 259 | char *data; /* start of rmgr data to include */ |
| 260 | uint32 len; /* length of rmgr data to include */ |
| 261 | } XLogRecData; |
| 262 | |
| 263 | /* |
| 264 | * Recovery target action. |
| 265 | */ |
| 266 | typedef enum |
| 267 | { |
| 268 | RECOVERY_TARGET_ACTION_PAUSE, |
| 269 | RECOVERY_TARGET_ACTION_PROMOTE, |
| 270 | RECOVERY_TARGET_ACTION_SHUTDOWN |
| 271 | } RecoveryTargetAction; |
| 272 | |
| 273 | /* |
| 274 | * Method table for resource managers. |
| 275 | * |
| 276 | * This struct must be kept in sync with the PG_RMGR definition in |
| 277 | * rmgr.c. |
| 278 | * |
| 279 | * rm_identify must return a name for the record based on xl_info (without |
| 280 | * reference to the rmid). For example, XLOG_BTREE_VACUUM would be named |
| 281 | * "VACUUM". rm_desc can then be called to obtain additional detail for the |
| 282 | * record, if available (e.g. the last block). |
| 283 | * |
| 284 | * rm_mask takes as input a page modified by the resource manager and masks |
| 285 | * out bits that shouldn't be flagged by wal_consistency_checking. |
| 286 | * |
| 287 | * RmgrTable[] is indexed by RmgrId values (see rmgrlist.h). |
| 288 | */ |
| 289 | typedef struct RmgrData |
| 290 | { |
| 291 | const char *rm_name; |
| 292 | void (*rm_redo) (XLogReaderState *record); |
| 293 | void (*rm_desc) (StringInfo buf, XLogReaderState *record); |
| 294 | const char *(*rm_identify) (uint8 info); |
| 295 | void (*rm_startup) (void); |
| 296 | void (*rm_cleanup) (void); |
| 297 | void (*rm_mask) (char *pagedata, BlockNumber blkno); |
| 298 | } RmgrData; |
| 299 | |
| 300 | extern const RmgrData RmgrTable[]; |
| 301 | |
| 302 | /* |
| 303 | * Exported to support xlog switching from checkpointer |
| 304 | */ |
| 305 | extern pg_time_t GetLastSegSwitchData(XLogRecPtr *lastSwitchLSN); |
| 306 | extern XLogRecPtr RequestXLogSwitch(bool mark_unimportant); |
| 307 | |
| 308 | extern void GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli); |
| 309 | |
| 310 | /* |
| 311 | * Exported for the functions in timeline.c and xlogarchive.c. Only valid |
| 312 | * in the startup process. |
| 313 | */ |
| 314 | extern bool ArchiveRecoveryRequested; |
| 315 | extern bool InArchiveRecovery; |
| 316 | extern bool StandbyMode; |
| 317 | extern char *recoveryRestoreCommand; |
| 318 | |
| 319 | /* |
| 320 | * Prototypes for functions in xlogarchive.c |
| 321 | */ |
| 322 | extern bool RestoreArchivedFile(char *path, const char *xlogfname, |
| 323 | const char *recovername, off_t expectedSize, |
| 324 | bool cleanupEnabled); |
| 325 | extern void ExecuteRecoveryCommand(const char *command, const char *commandName, |
| 326 | bool failOnerror); |
| 327 | extern void KeepFileRestoredFromArchive(const char *path, const char *xlogfname); |
| 328 | extern void XLogArchiveNotify(const char *xlog); |
| 329 | extern void XLogArchiveNotifySeg(XLogSegNo segno); |
| 330 | extern void XLogArchiveForceDone(const char *xlog); |
| 331 | extern bool XLogArchiveCheckDone(const char *xlog); |
| 332 | extern bool XLogArchiveIsBusy(const char *xlog); |
| 333 | extern bool XLogArchiveIsReady(const char *xlog); |
| 334 | extern bool XLogArchiveIsReadyOrDone(const char *xlog); |
| 335 | extern void XLogArchiveCleanup(const char *xlog); |
| 336 | |
| 337 | #endif /* XLOG_INTERNAL_H */ |
| 338 | |