]> granicus.if.org Git - postgresql/blob - src/include/access/xlog_internal.h
Clean up the #include mess a little.
[postgresql] / src / include / access / xlog_internal.h
1 /*
2  * xlog_internal.h
3  *
4  * PostgreSQL transaction 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 xlog.h.
10  *
11  * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
12  * Portions Copyright (c) 1994, Regents of the University of California
13  *
14  * src/include/access/xlog_internal.h
15  */
16 #ifndef XLOG_INTERNAL_H
17 #define XLOG_INTERNAL_H
18
19 #include "access/xlog.h"
20 #include "storage/block.h"
21 #include "storage/relfilenode.h"
22
23
24 /*
25  * Header info for a backup block appended to an XLOG record.
26  *
27  * As a trivial form of data compression, the XLOG code is aware that
28  * PG data pages usually contain an unused "hole" in the middle, which
29  * contains only zero bytes.  If hole_length > 0 then we have removed
30  * such a "hole" from the stored data (and it's not counted in the
31  * XLOG record's CRC, either).  Hence, the amount of block data actually
32  * present following the BkpBlock struct is BLCKSZ - hole_length bytes.
33  *
34  * Note that we don't attempt to align either the BkpBlock struct or the
35  * block's data.  So, the struct must be copied to aligned local storage
36  * before use.
37  */
38 typedef struct BkpBlock
39 {
40         RelFileNode node;                       /* relation containing block */
41         ForkNumber      fork;                   /* fork within the relation */
42         BlockNumber block;                      /* block number */
43         uint16          hole_offset;    /* number of bytes before "hole" */
44         uint16          hole_length;    /* number of bytes in "hole" */
45
46         /* ACTUAL BLOCK DATA FOLLOWS AT END OF STRUCT */
47 } BkpBlock;
48
49 /*
50  * When there is not enough space on current page for whole record, we
51  * continue on the next page with continuation record.  (However, the
52  * XLogRecord header will never be split across pages; if there's less than
53  * SizeOfXLogRecord space left at the end of a page, we just waste it.)
54  *
55  * Note that xl_rem_len includes backup-block data; that is, it tracks
56  * xl_tot_len not xl_len in the initial header.  Also note that the
57  * continuation data isn't necessarily aligned.
58  */
59 typedef struct XLogContRecord
60 {
61         uint32          xl_rem_len;             /* total len of remaining data for record */
62
63         /* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */
64
65 } XLogContRecord;
66
67 #define SizeOfXLogContRecord    sizeof(XLogContRecord)
68
69 /*
70  * Each page of XLOG file has a header like this:
71  */
72 #define XLOG_PAGE_MAGIC 0xD068  /* can be used as WAL version indicator */
73
74 typedef struct XLogPageHeaderData
75 {
76         uint16          xlp_magic;              /* magic value for correctness checks */
77         uint16          xlp_info;               /* flag bits, see below */
78         TimeLineID      xlp_tli;                /* TimeLineID of first record on page */
79         XLogRecPtr      xlp_pageaddr;   /* XLOG address of this page */
80 } XLogPageHeaderData;
81
82 #define SizeOfXLogShortPHD      MAXALIGN(sizeof(XLogPageHeaderData))
83
84 typedef XLogPageHeaderData *XLogPageHeader;
85
86 /*
87  * When the XLP_LONG_HEADER flag is set, we store additional fields in the
88  * page header.  (This is ordinarily done just in the first page of an
89  * XLOG file.)  The additional fields serve to identify the file accurately.
90  */
91 typedef struct XLogLongPageHeaderData
92 {
93         XLogPageHeaderData std;         /* standard header fields */
94         uint64          xlp_sysid;              /* system identifier from pg_control */
95         uint32          xlp_seg_size;   /* just as a cross-check */
96         uint32          xlp_xlog_blcksz;        /* just as a cross-check */
97 } XLogLongPageHeaderData;
98
99 #define SizeOfXLogLongPHD       MAXALIGN(sizeof(XLogLongPageHeaderData))
100
101 typedef XLogLongPageHeaderData *XLogLongPageHeader;
102
103 /* When record crosses page boundary, set this flag in new page's header */
104 #define XLP_FIRST_IS_CONTRECORD         0x0001
105 /* This flag indicates a "long" page header */
106 #define XLP_LONG_HEADER                         0x0002
107 /* All defined flag bits in xlp_info (used for validity checking of header) */
108 #define XLP_ALL_FLAGS                           0x0003
109
110 #define XLogPageHeaderSize(hdr)         \
111         (((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD)
112
113 /*
114  * We break each logical log file (xlogid value) into segment files of the
115  * size indicated by XLOG_SEG_SIZE.  One possible segment at the end of each
116  * log file is wasted, to ensure that we don't have problems representing
117  * last-byte-position-plus-1.
118  */
119 #define XLogSegSize             ((uint32) XLOG_SEG_SIZE)
120 #define XLogSegsPerFile (((uint32) 0xffffffff) / XLogSegSize)
121 #define XLogFileSize    (XLogSegsPerFile * XLogSegSize)
122
123
124 /*
125  * Macros for manipulating XLOG pointers
126  */
127
128 /* Increment an xlogid/segment pair */
129 #define NextLogSeg(logId, logSeg)       \
130         do { \
131                 if ((logSeg) >= XLogSegsPerFile-1) \
132                 { \
133                         (logId)++; \
134                         (logSeg) = 0; \
135                 } \
136                 else \
137                         (logSeg)++; \
138         } while (0)
139
140 /* Decrement an xlogid/segment pair (assume it's not 0,0) */
141 #define PrevLogSeg(logId, logSeg)       \
142         do { \
143                 if (logSeg) \
144                         (logSeg)--; \
145                 else \
146                 { \
147                         (logId)--; \
148                         (logSeg) = XLogSegsPerFile-1; \
149                 } \
150         } while (0)
151
152 /* Align a record pointer to next page */
153 #define NextLogPage(recptr) \
154         do {    \
155                 if ((recptr).xrecoff % XLOG_BLCKSZ != 0)        \
156                         (recptr).xrecoff +=     \
157                                 (XLOG_BLCKSZ - (recptr).xrecoff % XLOG_BLCKSZ); \
158                 if ((recptr).xrecoff >= XLogFileSize) \
159                 {       \
160                         ((recptr).xlogid)++;    \
161                         (recptr).xrecoff = 0; \
162                 }       \
163         } while (0)
164
165 /*
166  * Compute ID and segment from an XLogRecPtr.
167  *
168  * For XLByteToSeg, do the computation at face value.  For XLByteToPrevSeg,
169  * a boundary byte is taken to be in the previous segment.      This is suitable
170  * for deciding which segment to write given a pointer to a record end,
171  * for example.  (We can assume xrecoff is not zero, since no valid recptr
172  * can have that.)
173  */
174 #define XLByteToSeg(xlrp, logId, logSeg)        \
175         ( logId = (xlrp).xlogid, \
176           logSeg = (xlrp).xrecoff / XLogSegSize \
177         )
178 #define XLByteToPrevSeg(xlrp, logId, logSeg)    \
179         ( logId = (xlrp).xlogid, \
180           logSeg = ((xlrp).xrecoff - 1) / XLogSegSize \
181         )
182
183 /*
184  * Is an XLogRecPtr within a particular XLOG segment?
185  *
186  * For XLByteInSeg, do the computation at face value.  For XLByteInPrevSeg,
187  * a boundary byte is taken to be in the previous segment.
188  */
189 #define XLByteInSeg(xlrp, logId, logSeg)        \
190         ((xlrp).xlogid == (logId) && \
191          (xlrp).xrecoff / XLogSegSize == (logSeg))
192
193 #define XLByteInPrevSeg(xlrp, logId, logSeg)    \
194         ((xlrp).xlogid == (logId) && \
195          ((xlrp).xrecoff - 1) / XLogSegSize == (logSeg))
196
197 /* Check if an xrecoff value is in a plausible range */
198 #define XRecOffIsValid(xrecoff) \
199                 ((xrecoff) % XLOG_BLCKSZ >= SizeOfXLogShortPHD && \
200                 (XLOG_BLCKSZ - (xrecoff) % XLOG_BLCKSZ) >= SizeOfXLogRecord)
201
202 /*
203  * The XLog directory and control file (relative to $PGDATA)
204  */
205 #define XLOGDIR                         "pg_xlog"
206 #define XLOG_CONTROL_FILE       "global/pg_control"
207
208 /*
209  * These macros encapsulate knowledge about the exact layout of XLog file
210  * names, timeline history file names, and archive-status file names.
211  */
212 #define MAXFNAMELEN             64
213
214 #define XLogFileName(fname, tli, log, seg)      \
215         snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, log, seg)
216
217 #define XLogFromFileName(fname, tli, log, seg)  \
218         sscanf(fname, "%08X%08X%08X", tli, log, seg)
219
220 #define XLogFilePath(path, tli, log, seg)       \
221         snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli, log, seg)
222
223 #define TLHistoryFileName(fname, tli)   \
224         snprintf(fname, MAXFNAMELEN, "%08X.history", tli)
225
226 #define TLHistoryFilePath(path, tli)    \
227         snprintf(path, MAXPGPATH, XLOGDIR "/%08X.history", tli)
228
229 #define StatusFilePath(path, xlog, suffix)      \
230         snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix)
231
232 #define BackupHistoryFileName(fname, tli, log, seg, offset) \
233         snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli, log, seg, offset)
234
235 #define BackupHistoryFilePath(path, tli, log, seg, offset)      \
236         snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli, log, seg, offset)
237
238
239 /*
240  * Method table for resource managers.
241  *
242  * RmgrTable[] is indexed by RmgrId values (see rmgr.h).
243  */
244 typedef struct RmgrData
245 {
246         const char *rm_name;
247         void            (*rm_redo) (XLogRecPtr lsn, XLogRecord *rptr);
248         void            (*rm_desc) (StringInfo buf, uint8 xl_info, char *rec);
249         void            (*rm_startup) (void);
250         void            (*rm_cleanup) (void);
251         bool            (*rm_safe_restartpoint) (void);
252 } RmgrData;
253
254 extern const RmgrData RmgrTable[];
255
256 /*
257  * Exported to support xlog switching from bgwriter
258  */
259 extern pg_time_t GetLastSegSwitchTime(void);
260 extern XLogRecPtr RequestXLogSwitch(void);
261
262 /*
263  * These aren't in xlog.h because I'd rather not include fmgr.h there.
264  */
265 extern Datum pg_start_backup(PG_FUNCTION_ARGS);
266 extern Datum pg_stop_backup(PG_FUNCTION_ARGS);
267 extern Datum pg_switch_xlog(PG_FUNCTION_ARGS);
268 extern Datum pg_create_restore_point(PG_FUNCTION_ARGS);
269 extern Datum pg_current_xlog_location(PG_FUNCTION_ARGS);
270 extern Datum pg_current_xlog_insert_location(PG_FUNCTION_ARGS);
271 extern Datum pg_last_xlog_receive_location(PG_FUNCTION_ARGS);
272 extern Datum pg_last_xlog_replay_location(PG_FUNCTION_ARGS);
273 extern Datum pg_last_xact_replay_timestamp(PG_FUNCTION_ARGS);
274 extern Datum pg_xlogfile_name_offset(PG_FUNCTION_ARGS);
275 extern Datum pg_xlogfile_name(PG_FUNCTION_ARGS);
276 extern Datum pg_is_in_recovery(PG_FUNCTION_ARGS);
277 extern Datum pg_xlog_replay_pause(PG_FUNCTION_ARGS);
278 extern Datum pg_xlog_replay_resume(PG_FUNCTION_ARGS);
279 extern Datum pg_is_xlog_replay_paused(PG_FUNCTION_ARGS);
280
281 #endif   /* XLOG_INTERNAL_H */