summaryrefslogtreecommitdiff
path: root/src/include/access/xlog.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/access/xlog.h')
-rw-r--r--src/include/access/xlog.h171
1 files changed, 108 insertions, 63 deletions
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index c17bf32cc5..dd079496ed 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -3,7 +3,10 @@
*
* PostgreSQL transaction log manager
*
- * $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.18 2001/02/26 00:50:07 tgl Exp $
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $Id: xlog.h,v 1.19 2001/03/13 01:17:06 tgl Exp $
*/
#ifndef XLOG_H
#define XLOG_H
@@ -11,97 +14,126 @@
#include "access/rmgr.h"
#include "access/transam.h"
#include "access/xlogdefs.h"
-#include "access/xlogutils.h"
+#include "utils/pg_crc.h"
-typedef struct crc64
-{
- uint32 crc1;
- uint32 crc2;
-} crc64;
+/*
+ * Header for each record in XLOG
+ *
+ * NOTE: xl_len counts only the rmgr data, not the XLogRecord header,
+ * and also not any backup blocks appended to the record (which are signaled
+ * by xl_info flag bits). The total space needed for an XLOG record is
+ * really:
+ *
+ * SizeOfXLogRecord + xl_len + n_backup_blocks * (sizeof(BkpBlock) + BLCKSZ)
+ */
typedef struct XLogRecord
{
- crc64 xl_crc;
+ crc64 xl_crc; /* CRC for this record */
XLogRecPtr xl_prev; /* ptr to previous record in log */
XLogRecPtr xl_xact_prev; /* ptr to previous record of this xact */
TransactionId xl_xid; /* xact id */
- uint16 xl_len; /* total len of record *data* */
- uint8 xl_info;
- RmgrId xl_rmid; /* resource manager inserted this record */
+ uint16 xl_len; /* total len of rmgr data */
+ uint8 xl_info; /* flag bits, see below */
+ RmgrId xl_rmid; /* resource manager for this record */
/* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */
} XLogRecord;
-#define SizeOfXLogRecord DOUBLEALIGN(sizeof(XLogRecord))
-#define MAXLOGRECSZ (2 * BLCKSZ)
+#define SizeOfXLogRecord MAXALIGN(sizeof(XLogRecord))
+#define MAXLOGRECSZ 65535 /* the most that'll fit in xl_len */
-#define XLogRecGetData(record) \
- ((char*)record + SizeOfXLogRecord)
+#define XLogRecGetData(record) ((char*) (record) + SizeOfXLogRecord)
/*
- * When there is no space on current page we continue
- * on the next page with subrecord.
+ * XLOG uses only low 4 bits of xl_info. High 4 bits may be used by rmgr.
*/
-typedef struct XLogSubRecord
-{
- uint16 xl_len; /* len of data left */
-
- /* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */
-
-} XLogSubRecord;
-
-#define SizeOfXLogSubRecord DOUBLEALIGN(sizeof(XLogSubRecord))
+#define XLR_INFO_MASK 0x0F
/*
- * XLOG uses only low 4 bits of xl_info.
- * High 4 bits may be used by rmgr...
- *
- * We support backup of 2 blocks per record only.
- * If we backed up some of these blocks then we use
- * flags below to signal rmgr about this on recovery.
+ * We support backup of up to 2 disk blocks per XLOG record (could support
+ * more if we cared to dedicate more xl_info bits for this purpose; currently
+ * do not need more than 2 anyway). If we backed up any disk blocks then we
+ * use flag bits in xl_info to signal it.
*/
-#define XLR_SET_BKP_BLOCK(iblk) (0x08 >> iblk)
+#define XLR_BKP_BLOCK_MASK 0x0C /* all info bits used for bkp blocks */
+#define XLR_MAX_BKP_BLOCKS 2
+#define XLR_SET_BKP_BLOCK(iblk) (0x08 >> (iblk))
#define XLR_BKP_BLOCK_1 XLR_SET_BKP_BLOCK(0) /* 0x08 */
#define XLR_BKP_BLOCK_2 XLR_SET_BKP_BLOCK(1) /* 0x04 */
-#define XLR_INFO_MASK 0x0F
/*
* Sometimes we log records which are out of transaction control.
- * Rmgr may use flag below for this purpose.
+ * Rmgr may "or" XLOG_NO_TRAN into info passed to XLogInsert to indicate this.
*/
#define XLOG_NO_TRAN XLR_INFO_MASK
-#define XLOG_PAGE_MAGIC 0x17345168
+/*
+ * Header info for a backup block appended to an XLOG record.
+ *
+ * Note that the backup block has its own CRC, and is not covered by
+ * the CRC of the XLOG record proper. Also note that we don't attempt
+ * to align either the BkpBlock struct or the block's data.
+ */
+typedef struct BkpBlock
+{
+ crc64 crc;
+ RelFileNode node;
+ BlockNumber block;
+} BkpBlock;
-typedef struct XLogPageHeaderData
+/*
+ * When there is not enough space on current page for whole record, we
+ * continue on the next page with continuation record. (However, the
+ * XLogRecord header will never be split across pages; if there's less than
+ * SizeOfXLogRecord space left at the end of a page, we just waste it.)
+ *
+ * Note that xl_rem_len includes backup-block data, unlike xl_len in the
+ * initial header.
+ */
+typedef struct XLogContRecord
{
- uint32 xlp_magic;
- uint16 xlp_info;
-} XLogPageHeaderData;
+ uint32 xl_rem_len; /* total len of remaining data for record */
-#define SizeOfXLogPHD DOUBLEALIGN(sizeof(XLogPageHeaderData))
+ /* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */
-typedef XLogPageHeaderData *XLogPageHeader;
+} XLogContRecord;
-/* When record crosses page boundary */
-#define XLP_FIRST_IS_SUBRECORD 0x0001
+#define SizeOfXLogContRecord MAXALIGN(sizeof(XLogContRecord))
-#define XLByteLT(left, right) \
- (right.xlogid > left.xlogid || \
- (right.xlogid == left.xlogid && right.xrecoff > left.xrecoff))
+/*
+ * Each page of XLOG file has a header like this:
+ */
+#define XLOG_PAGE_MAGIC 0x17345169 /* can be used as WAL version indicator */
-#define XLByteLE(left, right) \
- (right.xlogid > left.xlogid || \
- (right.xlogid == left.xlogid && right.xrecoff >= left.xrecoff))
+typedef struct XLogPageHeaderData
+{
+ uint32 xlp_magic; /* magic value for correctness checks */
+ uint16 xlp_info; /* flag bits, see below */
+} XLogPageHeaderData;
-#define XLByteEQ(left, right) \
- (right.xlogid == left.xlogid && right.xrecoff == left.xrecoff)
+#define SizeOfXLogPHD MAXALIGN(sizeof(XLogPageHeaderData))
-extern StartUpID ThisStartUpID; /* current SUI */
-extern bool InRecovery;
-extern XLogRecPtr MyLastRecPtr;
+typedef XLogPageHeaderData *XLogPageHeader;
+
+/* When record crosses page boundary, set this flag in new page's header */
+#define XLP_FIRST_IS_CONTRECORD 0x0001
+
+/*
+ * We break each logical log file (xlogid value) into 16Mb segments.
+ * One possible segment at the end of each log file is wasted, to ensure
+ * that we don't have problems representing last-byte-position-plus-1.
+ */
+#define XLogSegSize ((uint32) (16*1024*1024))
+#define XLogSegsPerFile (((uint32) 0xffffffff) / XLogSegSize)
+#define XLogFileSize (XLogSegsPerFile * XLogSegSize)
+/*
+ * Method table for resource managers.
+ *
+ * RmgrTable[] is indexed by RmgrId values (see rmgr.h).
+ */
typedef struct RmgrData
{
char *rm_name;
@@ -112,12 +144,19 @@ typedef struct RmgrData
extern RmgrData RmgrTable[];
-/*
- * List of these structs is used to pass data to XLOG.
- * If buffer is valid then XLOG will check if buffer must
- * be backup-ed. For backup-ed buffer data will not be
- * inserted into record (and XLOG sets
- * XLR_BKP_BLOCK_X bit in xl_info).
+/*--------------------
+ * List of these structs is used to pass data to XLogInsert().
+ *
+ * If buffer is valid then XLOG will check if buffer must be backed up
+ * (ie, whether this is first change of that page since last checkpoint).
+ * If so, the whole page contents are attached to the XLOG record, and XLOG
+ * sets XLR_BKP_BLOCK_X bit in xl_info. Note that the buffer must be pinned
+ * and locked while this is going on, so that it won't change under us.
+ * NB: when this happens, we do not bother to insert the associated data into
+ * the XLOG record, since we assume it's present in the buffer. Therefore,
+ * rmgr redo routines MUST pay attention to XLR_BKP_BLOCK_X to know what
+ * is actually stored in the XLOG record.
+ *--------------------
*/
typedef struct XLogRecData
{
@@ -127,11 +166,13 @@ typedef struct XLogRecData
struct XLogRecData *next;
} XLogRecData;
+extern StartUpID ThisStartUpID; /* current SUI */
+extern bool InRecovery;
+extern XLogRecPtr MyLastRecPtr;
+
extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata);
extern void XLogFlush(XLogRecPtr RecPtr);
-extern void CreateCheckPoint(bool shutdown);
-
extern void xlog_redo(XLogRecPtr lsn, XLogRecord *record);
extern void xlog_undo(XLogRecPtr lsn, XLogRecord *record);
extern void xlog_desc(char *buf, uint8 xl_info, char* rec);
@@ -145,6 +186,10 @@ extern void StartupXLOG(void);
extern void ShutdownXLOG(void);
extern void CreateCheckPoint(bool shutdown);
extern void SetThisStartUpID(void);
+extern void XLogPutNextXid(TransactionId nextXid);
+extern void XLogPutNextOid(Oid nextOid);
+extern void SetRedoRecPtr(void);
+extern void GetRedoRecPtr(void);
/* in storage/ipc/sinval.c, but don't want to declare in sinval.h because
* we'd have to include xlog.h into that ...