aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access')
-rw-r--r--src/backend/access/heap/heapam.c36
-rw-r--r--src/backend/access/nbtree/nbtinsert.c20
-rw-r--r--src/backend/access/nbtree/nbtpage.c24
-rw-r--r--src/backend/access/nbtree/nbtsort.c6
-rw-r--r--src/backend/access/transam/clog.c4
-rw-r--r--src/backend/access/transam/xact.c20
-rw-r--r--src/backend/access/transam/xlog.c118
7 files changed, 129 insertions, 99 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index fa9f1a20763..433a4b4538c 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.192 2005/06/06 17:01:22 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.193 2005/06/06 20:22:56 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -1107,9 +1107,9 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid)
xlrec.target.node = relation->rd_node;
xlrec.target.tid = tup->t_self;
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfHeapInsert;
+ rdata[0].buffer = InvalidBuffer;
rdata[0].next = &(rdata[1]);
xlhdr.t_natts = tup->t_data->t_natts;
@@ -1121,15 +1121,17 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid)
* decides to write the whole page to the xlog, we don't need to
* store xl_heap_header in the xlog.
*/
- rdata[1].buffer = buffer;
rdata[1].data = (char *) &xlhdr;
rdata[1].len = SizeOfHeapHeader;
+ rdata[1].buffer = buffer;
+ rdata[1].buffer_std = true;
rdata[1].next = &(rdata[2]);
- rdata[2].buffer = buffer;
/* PG73FORMAT: write bitmap [+ padding] [+ oid] + data */
rdata[2].data = (char *) tup->t_data + offsetof(HeapTupleHeaderData, t_bits);
rdata[2].len = tup->t_len - offsetof(HeapTupleHeaderData, t_bits);
+ rdata[2].buffer = buffer;
+ rdata[2].buffer_std = true;
rdata[2].next = NULL;
/*
@@ -1378,14 +1380,15 @@ l1:
xlrec.target.node = relation->rd_node;
xlrec.target.tid = tp.t_self;
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfHeapDelete;
+ rdata[0].buffer = InvalidBuffer;
rdata[0].next = &(rdata[1]);
- rdata[1].buffer = buffer;
rdata[1].data = NULL;
rdata[1].len = 0;
+ rdata[1].buffer = buffer;
+ rdata[1].buffer_std = true;
rdata[1].next = NULL;
recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE, rdata);
@@ -2226,14 +2229,15 @@ l3:
xlrec.target.node = relation->rd_node;
xlrec.target.tid = tuple->t_self;
xlrec.shared_lock = (mode == LockTupleShared);
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfHeapLock;
+ rdata[0].buffer = InvalidBuffer;
rdata[0].next = &(rdata[1]);
- rdata[1].buffer = *buffer;
rdata[1].data = NULL;
rdata[1].len = 0;
+ rdata[1].buffer = *buffer;
+ rdata[1].buffer_std = true;
rdata[1].next = NULL;
recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK, rdata);
@@ -2330,9 +2334,9 @@ log_heap_clean(Relation reln, Buffer buffer, OffsetNumber *unused, int uncnt)
xlrec.node = reln->rd_node;
xlrec.block = BufferGetBlockNumber(buffer);
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfHeapClean;
+ rdata[0].buffer = InvalidBuffer;
rdata[0].next = &(rdata[1]);
/*
@@ -2340,7 +2344,6 @@ log_heap_clean(Relation reln, Buffer buffer, OffsetNumber *unused, int uncnt)
* that it is. When XLogInsert stores the whole buffer, the offsets
* array need not be stored too.
*/
- rdata[1].buffer = buffer;
if (uncnt > 0)
{
rdata[1].data = (char *) unused;
@@ -2351,6 +2354,8 @@ log_heap_clean(Relation reln, Buffer buffer, OffsetNumber *unused, int uncnt)
rdata[1].data = NULL;
rdata[1].len = 0;
}
+ rdata[1].buffer = buffer;
+ rdata[1].buffer_std = true;
rdata[1].next = NULL;
recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_CLEAN, rdata);
@@ -2388,14 +2393,15 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
xlrec.target.node = reln->rd_node;
xlrec.target.tid = from;
xlrec.newtid = newtup->t_self;
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfHeapUpdate;
+ rdata[0].buffer = InvalidBuffer;
rdata[0].next = &(rdata[1]);
- rdata[1].buffer = oldbuf;
rdata[1].data = NULL;
rdata[1].len = 0;
+ rdata[1].buffer = oldbuf;
+ rdata[1].buffer_std = true;
rdata[1].next = &(rdata[2]);
xlhdr.hdr.t_natts = newtup->t_data->t_natts;
@@ -2420,15 +2426,17 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
* As with insert records, we need not store the rdata[2] segment if
* we decide to store the whole buffer instead.
*/
- rdata[2].buffer = newbuf;
rdata[2].data = (char *) &xlhdr;
rdata[2].len = hsize;
+ rdata[2].buffer = newbuf;
+ rdata[2].buffer_std = true;
rdata[2].next = &(rdata[3]);
- rdata[3].buffer = newbuf;
/* PG73FORMAT: write bitmap [+ padding] [+ oid] + data */
rdata[3].data = (char *) newtup->t_data + offsetof(HeapTupleHeaderData, t_bits);
rdata[3].len = newtup->t_len - offsetof(HeapTupleHeaderData, t_bits);
+ rdata[3].buffer = newbuf;
+ rdata[3].buffer_std = true;
rdata[3].next = NULL;
/* If new tuple is the single and first tuple on page... */
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
index 868a91ab3a5..9b9fa44e6ed 100644
--- a/src/backend/access/nbtree/nbtinsert.c
+++ b/src/backend/access/nbtree/nbtinsert.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.120 2005/03/21 01:23:59 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.121 2005/06/06 20:22:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -564,9 +564,9 @@ _bt_insertonpg(Relation rel,
xlrec.target.node = rel->rd_node;
ItemPointerSet(&(xlrec.target.tid), itup_blkno, itup_off);
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfBtreeInsert;
+ rdata[0].buffer = InvalidBuffer;
rdata[0].next = nextrdata = &(rdata[1]);
if (BufferIsValid(metabuf))
@@ -576,9 +576,9 @@ _bt_insertonpg(Relation rel,
xlmeta.fastroot = metad->btm_fastroot;
xlmeta.fastlevel = metad->btm_fastlevel;
- nextrdata->buffer = InvalidBuffer;
nextrdata->data = (char *) &xlmeta;
nextrdata->len = sizeof(xl_btree_metadata);
+ nextrdata->buffer = InvalidBuffer;
nextrdata->next = nextrdata + 1;
nextrdata++;
xlinfo = XLOG_BTREE_INSERT_META;
@@ -603,6 +603,7 @@ _bt_insertonpg(Relation rel,
(sizeof(BTItemData) - sizeof(IndexTupleData));
}
nextrdata->buffer = buf;
+ nextrdata->buffer_std = true;
nextrdata->next = NULL;
recptr = XLogInsert(RM_BTREE_ID, xlinfo, rdata);
@@ -853,28 +854,29 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright,
xlrec.leftlen = ((PageHeader) leftpage)->pd_special -
((PageHeader) leftpage)->pd_upper;
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfBtreeSplit;
+ rdata[0].buffer = InvalidBuffer;
rdata[0].next = &(rdata[1]);
- rdata[1].buffer = InvalidBuffer;
rdata[1].data = (char *) leftpage + ((PageHeader) leftpage)->pd_upper;
rdata[1].len = xlrec.leftlen;
+ rdata[1].buffer = InvalidBuffer;
rdata[1].next = &(rdata[2]);
- rdata[2].buffer = InvalidBuffer;
rdata[2].data = (char *) rightpage + ((PageHeader) rightpage)->pd_upper;
rdata[2].len = ((PageHeader) rightpage)->pd_special -
((PageHeader) rightpage)->pd_upper;
+ rdata[2].buffer = InvalidBuffer;
rdata[2].next = NULL;
if (!P_RIGHTMOST(ropaque))
{
rdata[2].next = &(rdata[3]);
- rdata[3].buffer = sbuf;
rdata[3].data = NULL;
rdata[3].len = 0;
+ rdata[3].buffer = sbuf;
+ rdata[3].buffer_std = true;
rdata[3].next = NULL;
}
@@ -1464,19 +1466,19 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
xlrec.rootblk = rootblknum;
xlrec.level = metad->btm_level;
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfBtreeNewroot;
+ rdata[0].buffer = InvalidBuffer;
rdata[0].next = &(rdata[1]);
/*
* Direct access to page is not good but faster - we should
* implement some new func in page API.
*/
- rdata[1].buffer = InvalidBuffer;
rdata[1].data = (char *) rootpage + ((PageHeader) rootpage)->pd_upper;
rdata[1].len = ((PageHeader) rootpage)->pd_special -
((PageHeader) rootpage)->pd_upper;
+ rdata[1].buffer = InvalidBuffer;
rdata[1].next = NULL;
recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_NEWROOT, rdata);
diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c
index b9d42bad6d2..f3ce5bd64a9 100644
--- a/src/backend/access/nbtree/nbtpage.c
+++ b/src/backend/access/nbtree/nbtpage.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtpage.c,v 1.85 2005/06/02 05:55:28 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtpage.c,v 1.86 2005/06/06 20:22:57 tgl Exp $
*
* NOTES
* Postgres btree pages look like ordinary relation pages. The opaque
@@ -74,9 +74,9 @@ _bt_metapinit(Relation rel)
xlrec.meta.fastroot = metad->btm_fastroot;
xlrec.meta.fastlevel = metad->btm_fastlevel;
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfBtreeNewmeta;
+ rdata[0].buffer = InvalidBuffer;
rdata[0].next = NULL;
recptr = XLogInsert(RM_BTREE_ID,
@@ -248,9 +248,9 @@ _bt_getroot(Relation rel, int access)
xlrec.rootblk = rootblkno;
xlrec.level = 0;
- rdata.buffer = InvalidBuffer;
rdata.data = (char *) &xlrec;
rdata.len = SizeOfBtreeNewroot;
+ rdata.buffer = InvalidBuffer;
rdata.next = NULL;
recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_NEWROOT, &rdata);
@@ -666,9 +666,9 @@ _bt_delitems(Relation rel, Buffer buf,
xlrec.node = rel->rd_node;
xlrec.block = BufferGetBlockNumber(buf);
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfBtreeDelete;
+ rdata[0].buffer = InvalidBuffer;
rdata[0].next = &(rdata[1]);
/*
@@ -676,7 +676,6 @@ _bt_delitems(Relation rel, Buffer buf,
* it is. When XLogInsert stores the whole buffer, the offsets
* array need not be stored too.
*/
- rdata[1].buffer = buf;
if (nitems > 0)
{
rdata[1].data = (char *) itemnos;
@@ -687,6 +686,8 @@ _bt_delitems(Relation rel, Buffer buf,
rdata[1].data = NULL;
rdata[1].len = 0;
}
+ rdata[1].buffer = buf;
+ rdata[1].buffer_std = true;
rdata[1].next = NULL;
recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_DELETE, rdata);
@@ -1038,9 +1039,9 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
xlrec.leftblk = leftsib;
xlrec.rightblk = rightsib;
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfBtreeDeletePage;
+ rdata[0].buffer = InvalidBuffer;
rdata[0].next = nextrdata = &(rdata[1]);
if (BufferIsValid(metabuf))
@@ -1050,9 +1051,9 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
xlmeta.fastroot = metad->btm_fastroot;
xlmeta.fastlevel = metad->btm_fastlevel;
- nextrdata->buffer = InvalidBuffer;
nextrdata->data = (char *) &xlmeta;
nextrdata->len = sizeof(xl_btree_metadata);
+ nextrdata->buffer = InvalidBuffer;
nextrdata->next = nextrdata + 1;
nextrdata++;
xlinfo = XLOG_BTREE_DELETE_PAGE_META;
@@ -1060,24 +1061,27 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
else
xlinfo = XLOG_BTREE_DELETE_PAGE;
- nextrdata->buffer = pbuf;
nextrdata->data = NULL;
nextrdata->len = 0;
nextrdata->next = nextrdata + 1;
+ nextrdata->buffer = pbuf;
+ nextrdata->buffer_std = true;
nextrdata++;
- nextrdata->buffer = rbuf;
nextrdata->data = NULL;
nextrdata->len = 0;
+ nextrdata->buffer = rbuf;
+ nextrdata->buffer_std = true;
nextrdata->next = NULL;
if (BufferIsValid(lbuf))
{
nextrdata->next = nextrdata + 1;
nextrdata++;
- nextrdata->buffer = lbuf;
nextrdata->data = NULL;
nextrdata->len = 0;
+ nextrdata->buffer = lbuf;
+ nextrdata->buffer_std = true;
nextrdata->next = NULL;
}
diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c
index 01104015118..115708b7809 100644
--- a/src/backend/access/nbtree/nbtsort.c
+++ b/src/backend/access/nbtree/nbtsort.c
@@ -56,7 +56,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsort.c,v 1.90 2004/12/31 21:59:22 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsort.c,v 1.91 2005/06/06 20:22:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -287,14 +287,14 @@ _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno)
xlrec.node = wstate->index->rd_node;
xlrec.blkno = blkno;
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfHeapNewpage;
+ rdata[0].buffer = InvalidBuffer;
rdata[0].next = &(rdata[1]);
- rdata[1].buffer = InvalidBuffer;
rdata[1].data = (char *) page;
rdata[1].len = BLCKSZ;
+ rdata[1].buffer = InvalidBuffer;
rdata[1].next = NULL;
recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_NEWPAGE, rdata);
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 73362330c10..2da835dbbe5 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -24,7 +24,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.29 2005/06/06 17:01:22 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.30 2005/06/06 20:22:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -379,9 +379,9 @@ WriteZeroPageXlogRec(int pageno)
{
XLogRecData rdata;
- rdata.buffer = InvalidBuffer;
rdata.data = (char *) (&pageno);
rdata.len = sizeof(int);
+ rdata.buffer = InvalidBuffer;
rdata.next = NULL;
(void) XLogInsert(RM_CLOG_ID, CLOG_ZEROPAGE | XLOG_NO_TRAN, &rdata);
}
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 3eb58a96a8d..040a4ab0b79 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.203 2005/06/06 17:01:22 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.204 2005/06/06 20:22:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -719,25 +719,25 @@ RecordTransactionCommit(void)
xlrec.xtime = time(NULL);
xlrec.nrels = nrels;
xlrec.nsubxacts = nchildren;
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) (&xlrec);
rdata[0].len = MinSizeOfXactCommit;
+ rdata[0].buffer = InvalidBuffer;
/* dump rels to delete */
if (nrels > 0)
{
rdata[0].next = &(rdata[1]);
- rdata[1].buffer = InvalidBuffer;
rdata[1].data = (char *) rptr;
rdata[1].len = nrels * sizeof(RelFileNode);
+ rdata[1].buffer = InvalidBuffer;
lastrdata = 1;
}
/* dump committed child Xids */
if (nchildren > 0)
{
rdata[lastrdata].next = &(rdata[2]);
- rdata[2].buffer = InvalidBuffer;
rdata[2].data = (char *) children;
rdata[2].len = nchildren * sizeof(TransactionId);
+ rdata[2].buffer = InvalidBuffer;
lastrdata = 2;
}
rdata[lastrdata].next = NULL;
@@ -1019,25 +1019,25 @@ RecordTransactionAbort(void)
xlrec.xtime = time(NULL);
xlrec.nrels = nrels;
xlrec.nsubxacts = nchildren;
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) (&xlrec);
rdata[0].len = MinSizeOfXactAbort;
+ rdata[0].buffer = InvalidBuffer;
/* dump rels to delete */
if (nrels > 0)
{
rdata[0].next = &(rdata[1]);
- rdata[1].buffer = InvalidBuffer;
rdata[1].data = (char *) rptr;
rdata[1].len = nrels * sizeof(RelFileNode);
+ rdata[1].buffer = InvalidBuffer;
lastrdata = 1;
}
/* dump committed child Xids */
if (nchildren > 0)
{
rdata[lastrdata].next = &(rdata[2]);
- rdata[2].buffer = InvalidBuffer;
rdata[2].data = (char *) children;
rdata[2].len = nchildren * sizeof(TransactionId);
+ rdata[2].buffer = InvalidBuffer;
lastrdata = 2;
}
rdata[lastrdata].next = NULL;
@@ -1205,25 +1205,25 @@ RecordSubTransactionAbort(void)
xlrec.xtime = time(NULL);
xlrec.nrels = nrels;
xlrec.nsubxacts = nchildren;
- rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char *) (&xlrec);
rdata[0].len = MinSizeOfXactAbort;
+ rdata[0].buffer = InvalidBuffer;
/* dump rels to delete */
if (nrels > 0)
{
rdata[0].next = &(rdata[1]);
- rdata[1].buffer = InvalidBuffer;
rdata[1].data = (char *) rptr;
rdata[1].len = nrels * sizeof(RelFileNode);
+ rdata[1].buffer = InvalidBuffer;
lastrdata = 1;
}
/* dump committed child Xids */
if (nchildren > 0)
{
rdata[lastrdata].next = &(rdata[2]);
- rdata[2].buffer = InvalidBuffer;
rdata[2].data = (char *) children;
rdata[2].len = nchildren * sizeof(TransactionId);
+ rdata[2].buffer = InvalidBuffer;
lastrdata = 2;
}
rdata[lastrdata].next = NULL;
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index c1609356d39..aa37244162a 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.196 2005/06/06 17:01:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.197 2005/06/06 20:22:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -434,7 +434,8 @@ static void exitArchiveRecovery(TimeLineID endTLI,
uint32 endLogId, uint32 endLogSeg);
static bool recoveryStopsHere(XLogRecord *record, bool *includeThis);
-static void SetBkpBlock(BkpBlock *bkpb, Buffer buffer);
+static bool XLogCheckBuffer(XLogRecData *rdata,
+ XLogRecPtr *lsn, BkpBlock *bkpb);
static bool AdvanceXLInsertBuffer(void);
static void XLogWrite(XLogwrtRqst WriteRqst);
static int XLogFileInit(uint32 log, uint32 seg,
@@ -473,7 +474,7 @@ static void remove_backup_label(void);
/*
* Insert an XLOG record having the specified RMID and info bytes,
* with the body of the record being the data chunk(s) described by
- * the rdata list (see xlog.h for notes about rdata).
+ * the rdata chain (see xlog.h for notes about rdata).
*
* Returns XLOG pointer to end of record (beginning of next record).
* This can be used as LSN for data pages affected by the logged action.
@@ -532,7 +533,7 @@ XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata)
}
/*
- * Here we scan the rdata list, determine which buffers must be backed
+ * Here we scan the rdata chain, determine which buffers must be backed
* up, and compute the CRC values for the data. Note that the record
* header isn't added into the CRC initially since we don't know the
* final length or info bits quite yet. Thus, the CRC will represent
@@ -543,13 +544,13 @@ XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata)
* below. We could prevent the race by doing all this work while
* holding the insert lock, but it seems better to avoid doing CRC
* calculations while holding the lock. This means we have to be
- * careful about modifying the rdata list until we know we aren't
+ * careful about modifying the rdata chain until we know we aren't
* going to loop back again. The only change we allow ourselves to
- * make earlier is to set rdt->data = NULL in list items we have
+ * make earlier is to set rdt->data = NULL in chain items we have
* decided we will have to back up the whole buffer for. This is OK
* because we will certainly decide the same thing again for those
* items if we do it over; doing it here saves an extra pass over the
- * list later.
+ * chain later.
*/
begin:;
for (i = 0; i < XLR_MAX_BKP_BLOCKS; i++)
@@ -575,7 +576,7 @@ begin:;
{
if (rdt->buffer == dtbuf[i])
{
- /* Buffer already referenced by earlier list item */
+ /* Buffer already referenced by earlier chain item */
if (dtbuf_bkp[i])
rdt->data = NULL;
else if (rdt->data)
@@ -589,15 +590,9 @@ begin:;
{
/* OK, put it in this slot */
dtbuf[i] = rdt->buffer;
-
- /*
- * XXX We assume page LSN is first data on page
- */
- dtbuf_lsn[i] = *((XLogRecPtr *) BufferGetBlock(rdt->buffer));
- if (XLByteLE(dtbuf_lsn[i], RedoRecPtr))
+ if (XLogCheckBuffer(rdt, &(dtbuf_lsn[i]), &(dtbuf_xlg[i])))
{
dtbuf_bkp[i] = true;
- SetBkpBlock(&(dtbuf_xlg[i]), rdt->buffer);
rdt->data = NULL;
}
else if (rdt->data)
@@ -612,7 +607,7 @@ begin:;
elog(PANIC, "can backup at most %d blocks per xlog record",
XLR_MAX_BKP_BLOCKS);
}
- /* Break out of loop when rdt points to last list item */
+ /* Break out of loop when rdt points to last chain item */
if (rdt->next == NULL)
break;
rdt = rdt->next;
@@ -726,15 +721,15 @@ begin:;
}
/*
- * Make additional rdata list entries for the backup blocks, so that
+ * Make additional rdata chain entries for the backup blocks, so that
* we don't need to special-case them in the write loop. Note that we
- * have now irrevocably changed the input rdata list. At the exit of
+ * have now irrevocably changed the input rdata chain. At the exit of
* this loop, write_len includes the backup block data.
*
* Also set the appropriate info bits to show which buffers were backed
* up. The i'th XLR_SET_BKP_BLOCK bit corresponds to the i'th
* distinct buffer value (ignoring InvalidBuffer) appearing in the
- * rdata list.
+ * rdata chain.
*/
write_len = len;
for (i = 0; i < XLR_MAX_BKP_BLOCKS; i++)
@@ -742,7 +737,7 @@ begin:;
BkpBlock *bkpb;
char *page;
- if (dtbuf[i] == InvalidBuffer || !(dtbuf_bkp[i]))
+ if (!dtbuf_bkp[i])
continue;
info |= XLR_SET_BKP_BLOCK(i);
@@ -938,43 +933,64 @@ begin:;
}
/*
- * Fill a BkpBlock struct given a buffer containing the page to be saved
- *
- * This is nontrivial only because it has to decide whether to apply "hole
- * compression".
+ * Determine whether the buffer referenced by an XLogRecData item has to
+ * be backed up, and if so fill a BkpBlock struct for it. In any case
+ * save the buffer's LSN at *lsn.
*/
-static void
-SetBkpBlock(BkpBlock *bkpb, Buffer buffer)
+static bool
+XLogCheckBuffer(XLogRecData *rdata,
+ XLogRecPtr *lsn, BkpBlock *bkpb)
{
PageHeader page;
- uint16 offset;
- uint16 length;
- /* Save page identity info */
- bkpb->node = BufferGetFileNode(buffer);
- bkpb->block = BufferGetBlockNumber(buffer);
+ page = (PageHeader) BufferGetBlock(rdata->buffer);
+
+ /*
+ * XXX We assume page LSN is first data on *every* page that can be
+ * passed to XLogInsert, whether it otherwise has the standard page
+ * layout or not.
+ */
+ *lsn = page->pd_lsn;
- /* Test whether there is a "hole" containing zeroes in the page */
- page = (PageHeader) BufferGetBlock(buffer);
- offset = page->pd_lower;
- /* Check if pd_lower appears sane at all */
- if (offset >= SizeOfPageHeaderData && offset < BLCKSZ)
+ if (XLByteLE(page->pd_lsn, RedoRecPtr))
{
- char *spd = (char *) page + offset;
- char *epd = (char *) page + BLCKSZ;
- char *pd = spd;
+ /*
+ * The page needs to be backed up, so set up *bkpb
+ */
+ bkpb->node = BufferGetFileNode(rdata->buffer);
+ bkpb->block = BufferGetBlockNumber(rdata->buffer);
+
+ if (rdata->buffer_std)
+ {
+ /* Assume we can omit data between pd_lower and pd_upper */
+ uint16 lower = page->pd_lower;
+ uint16 upper = page->pd_upper;
- while (pd < epd && *pd == '\0')
- pd++;
+ if (lower >= SizeOfPageHeaderData &&
+ upper > lower &&
+ upper <= BLCKSZ)
+ {
+ bkpb->hole_offset = lower;
+ bkpb->hole_length = upper - lower;
+ }
+ else
+ {
+ /* No "hole" to compress out */
+ bkpb->hole_offset = 0;
+ bkpb->hole_length = 0;
+ }
+ }
+ else
+ {
+ /* Not a standard page header, don't try to eliminate "hole" */
+ bkpb->hole_offset = 0;
+ bkpb->hole_length = 0;
+ }
- length = pd - spd;
- if (length == 0)
- offset = 0;
+ return true; /* buffer requires backup */
}
- else
- offset = length = 0;
- bkpb->hole_offset = offset;
- bkpb->hole_length = length;
+
+ return false; /* buffer does not need to be backed up */
}
/*
@@ -5093,9 +5109,9 @@ CreateCheckPoint(bool shutdown, bool force)
/*
* Now insert the checkpoint record into XLOG.
*/
- rdata.buffer = InvalidBuffer;
rdata.data = (char *) (&checkPoint);
rdata.len = sizeof(checkPoint);
+ rdata.buffer = InvalidBuffer;
rdata.next = NULL;
recptr = XLogInsert(RM_XLOG_ID,
@@ -5197,9 +5213,9 @@ XLogPutNextOid(Oid nextOid)
{
XLogRecData rdata;
- rdata.buffer = InvalidBuffer;
rdata.data = (char *) (&nextOid);
rdata.len = sizeof(Oid);
+ rdata.buffer = InvalidBuffer;
rdata.next = NULL;
(void) XLogInsert(RM_XLOG_ID, XLOG_NEXTOID, &rdata);
/*
@@ -5220,9 +5236,9 @@ XLogPutNextMultiXactId(MultiXactId nextMulti)
{
XLogRecData rdata;
- rdata.buffer = InvalidBuffer;
rdata.data = (char *) (&nextMulti);
rdata.len = sizeof(MultiXactId);
+ rdata.buffer = InvalidBuffer;
rdata.next = NULL;
(void) XLogInsert(RM_XLOG_ID, XLOG_NEXTMULTI, &rdata);
/*