Commit 7ceeeb66 authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

New WAL version - CRC and data blocks backup.

parent c996c7f5
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.70 2000/12/03 10:27:26 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.71 2000/12/28 13:00:07 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -520,39 +520,40 @@ _bt_insertonpg(Relation rel, ...@@ -520,39 +520,40 @@ _bt_insertonpg(Relation rel,
{ {
/* XLOG stuff */ /* XLOG stuff */
{ {
char xlbuf[sizeof(xl_btree_insert) + xl_btree_insert xlrec;
sizeof(CommandId) + sizeof(RelFileNode)]; uint8 flag = XLOG_BTREE_INSERT;
xl_btree_insert *xlrec = (xl_btree_insert*)xlbuf;
int hsize = SizeOfBtreeInsert;
BTItemData truncitem;
BTItem xlitem = btitem;
Size xlsize = IndexTupleDSize(btitem->bti_itup) +
(sizeof(BTItemData) - sizeof(IndexTupleData));
XLogRecPtr recptr; XLogRecPtr recptr;
XLogRecData rdata[2];
xlrec->target.node = rel->rd_node; xlrec.target.node = rel->rd_node;
ItemPointerSet(&(xlrec->target.tid), BufferGetBlockNumber(buf), newitemoff); ItemPointerSet(&(xlrec.target.tid), BufferGetBlockNumber(buf), newitemoff);
if (P_ISLEAF(lpageop)) rdata[0].buffer = InvalidBuffer;
{ rdata[0].data = (char*)&xlrec;
CommandId cid = GetCurrentCommandId(); rdata[0].len = SizeOfBtreeInsert;
memcpy(xlbuf + hsize, &cid, sizeof(CommandId)); rdata[0].next = &(rdata[1]);
hsize += sizeof(CommandId);
memcpy(xlbuf + hsize, &(_xlheapRel->rd_node), sizeof(RelFileNode)); /* Read comments in _bt_pgaddtup */
hsize += sizeof(RelFileNode); if (!(P_ISLEAF(lpageop)) && newitemoff == P_FIRSTDATAKEY(lpageop))
}
/*
* Read comments in _bt_pgaddtup
*/
else if (newitemoff == P_FIRSTDATAKEY(lpageop))
{ {
truncitem = *btitem; BTItemData truncitem = *btitem;
truncitem.bti_itup.t_info = sizeof(BTItemData); truncitem.bti_itup.t_info = sizeof(BTItemData);
xlitem = &truncitem; rdata[1].data = (char*)&truncitem;
xlsize = sizeof(BTItemData); rdata[1].len = sizeof(BTItemData);
}
else
{
rdata[1].data = (char*)btitem;
rdata[1].len = IndexTupleDSize(btitem->bti_itup) +
(sizeof(BTItemData) - sizeof(IndexTupleData));
} }
rdata[1].buffer = buf;
rdata[1].next = NULL;
recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_INSERT, if (P_ISLEAF(lpageop))
xlbuf, hsize, (char*) xlitem, xlsize); flag |= XLOG_BTREE_LEAF;
recptr = XLogInsert(RM_BTREE_ID, flag, rdata);
PageSetLSN(page, recptr); PageSetLSN(page, recptr);
PageSetSUI(page, ThisStartUpID); PageSetSUI(page, ThisStartUpID);
...@@ -774,71 +775,63 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright, ...@@ -774,71 +775,63 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright,
*/ */
START_CRIT_CODE; START_CRIT_CODE;
{ {
char xlbuf[sizeof(xl_btree_split) + xl_btree_split xlrec;
sizeof(CommandId) + sizeof(RelFileNode) + BLCKSZ]; int flag = (newitemonleft) ?
xl_btree_split *xlrec = (xl_btree_split*) xlbuf; XLOG_BTREE_SPLEFT : XLOG_BTREE_SPLIT;
int hsize = SizeOfBtreeSplit; BlockNumber blkno;
int flag = (newitemonleft) ? XLogRecPtr recptr;
XLOG_BTREE_SPLEFT : XLOG_BTREE_SPLIT; XLogRecData rdata[4];
BlockNumber blkno;
XLogRecPtr recptr; xlrec.target.node = rel->rd_node;
ItemPointerSet(&(xlrec.target.tid), *itup_blkno, *itup_off);
xlrec->target.node = rel->rd_node;
ItemPointerSet(&(xlrec->target.tid), *itup_blkno, *itup_off);
if (P_ISLEAF(lopaque))
{
CommandId cid = GetCurrentCommandId();
memcpy(xlbuf + hsize, &cid, sizeof(CommandId));
hsize += sizeof(CommandId);
memcpy(xlbuf + hsize, &(_xlheapRel->rd_node), sizeof(RelFileNode));
hsize += sizeof(RelFileNode);
}
else
{
Size itemsz = IndexTupleDSize(lhikey->bti_itup) +
(sizeof(BTItemData) - sizeof(IndexTupleData));
memcpy(xlbuf + hsize, (char*) lhikey, itemsz);
hsize += itemsz;
}
if (newitemonleft) if (newitemonleft)
{ {
/*
* Read comments in _bt_pgaddtup.
* Actually, seems that in non-leaf splits newitem shouldn't
* go to first data key position on left page.
*/
if (! P_ISLEAF(lopaque) && *itup_off == P_FIRSTDATAKEY(lopaque))
{
BTItemData truncitem = *newitem;
truncitem.bti_itup.t_info = sizeof(BTItemData);
memcpy(xlbuf + hsize, &truncitem, sizeof(BTItemData));
hsize += sizeof(BTItemData);
}
else
{
Size itemsz = IndexTupleDSize(newitem->bti_itup) +
(sizeof(BTItemData) - sizeof(IndexTupleData));
memcpy(xlbuf + hsize, (char*) newitem, itemsz);
hsize += itemsz;
}
blkno = BufferGetBlockNumber(rbuf); blkno = BufferGetBlockNumber(rbuf);
BlockIdSet(&(xlrec->otherblk), blkno); BlockIdSet(&(xlrec.otherblk), blkno);
} }
else else
{ {
blkno = BufferGetBlockNumber(buf); blkno = BufferGetBlockNumber(buf);
BlockIdSet(&(xlrec->otherblk), blkno); BlockIdSet(&(xlrec.otherblk), blkno);
} }
BlockIdSet(&(xlrec.parentblk), lopaque->btpo_parent);
BlockIdSet(&(xlrec->rightblk), ropaque->btpo_next); BlockIdSet(&(xlrec.leftblk), lopaque->btpo_prev);
BlockIdSet(&(xlrec.rightblk), ropaque->btpo_next);
/* /*
* Dirrect access to page is not good but faster - we should * Dirrect access to page is not good but faster - we should
* implement some new func in page API. * implement some new func in page API.
*/ */
recptr = XLogInsert(RM_BTREE_ID, flag, xlbuf, xlrec.leftlen = ((PageHeader)leftpage)->pd_special -
hsize, (char*)rightpage + ((PageHeader) rightpage)->pd_upper, ((PageHeader)leftpage)->pd_upper;
((PageHeader) rightpage)->pd_special - ((PageHeader) rightpage)->pd_upper); rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char*)&xlrec;
rdata[0].len = SizeOfBtreeSplit;
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].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].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].next = NULL;
}
if (P_ISLEAF(lopaque))
flag |= XLOG_BTREE_LEAF;
recptr = XLogInsert(RM_BTREE_ID, flag, rdata);
PageSetLSN(leftpage, recptr); PageSetLSN(leftpage, recptr);
PageSetSUI(leftpage, ThisStartUpID); PageSetSUI(leftpage, ThisStartUpID);
...@@ -1143,25 +1136,29 @@ _bt_getstackbuf(Relation rel, BTStack stack) ...@@ -1143,25 +1136,29 @@ _bt_getstackbuf(Relation rel, BTStack stack)
void void
_bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
{ {
Buffer rootbuf; Buffer rootbuf;
Page lpage, Page lpage,
rpage, rpage,
rootpage; rootpage;
BlockNumber lbkno, BlockNumber lbkno,
rbkno; rbkno;
BlockNumber rootblknum; BlockNumber rootblknum;
BTPageOpaque rootopaque; BTPageOpaque rootopaque;
ItemId itemid; ItemId itemid;
BTItem item; BTItem item;
Size itemsz; Size itemsz;
BTItem new_item; BTItem new_item;
Buffer metabuf; Buffer metabuf;
Page metapg;
BTMetaPageData *metad;
/* get a new root page */ /* get a new root page */
rootbuf = _bt_getbuf(rel, P_NEW, BT_WRITE); rootbuf = _bt_getbuf(rel, P_NEW, BT_WRITE);
rootpage = BufferGetPage(rootbuf); rootpage = BufferGetPage(rootbuf);
rootblknum = BufferGetBlockNumber(rootbuf); rootblknum = BufferGetBlockNumber(rootbuf);
metabuf = _bt_getbuf(rel, BTREE_METAPAGE,BT_WRITE); metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE);
metapg = BufferGetPage(metabuf);
metad = BTPageGetMeta(metapg);
/* NO ELOG(ERROR) from here till newroot op is logged */ /* NO ELOG(ERROR) from here till newroot op is logged */
START_CRIT_CODE; START_CRIT_CODE;
...@@ -1222,39 +1219,46 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) ...@@ -1222,39 +1219,46 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
elog(STOP, "btree: failed to add rightkey to new root page"); elog(STOP, "btree: failed to add rightkey to new root page");
pfree(new_item); pfree(new_item);
metad->btm_root = rootblknum;
(metad->btm_level)++;
/* XLOG stuff */ /* XLOG stuff */
{ {
xl_btree_newroot xlrec; xl_btree_newroot xlrec;
Page metapg = BufferGetPage(metabuf);
BTMetaPageData *metad = BTPageGetMeta(metapg);
XLogRecPtr recptr; XLogRecPtr recptr;
XLogRecData rdata[2];
xlrec.node = rel->rd_node; xlrec.node = rel->rd_node;
xlrec.level = metad->btm_level;
BlockIdSet(&(xlrec.rootblk), rootblknum); BlockIdSet(&(xlrec.rootblk), rootblknum);
rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char*)&xlrec;
rdata[0].len = SizeOfBtreeNewroot;
rdata[0].next = &(rdata[1]);
/* /*
* Dirrect access to page is not good but faster - we should * Dirrect access to page is not good but faster - we should
* implement some new func in page API. * implement some new func in page API.
*/ */
recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_NEWROOT, rdata[1].buffer = InvalidBuffer;
(char*)&xlrec, SizeOfBtreeNewroot, rdata[1].data = (char*)rootpage + ((PageHeader) rootpage)->pd_upper;
(char*)rootpage + ((PageHeader) rootpage)->pd_upper, rdata[1].len = ((PageHeader)rootpage)->pd_special -
((PageHeader) rootpage)->pd_special - ((PageHeader) rootpage)->pd_upper); ((PageHeader)rootpage)->pd_upper;
rdata[1].next = NULL;
metad->btm_root = rootblknum; recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_NEWROOT, rdata);
(metad->btm_level)++;
PageSetLSN(rootpage, recptr); PageSetLSN(rootpage, recptr);
PageSetSUI(rootpage, ThisStartUpID); PageSetSUI(rootpage, ThisStartUpID);
PageSetLSN(metapg, recptr); PageSetLSN(metapg, recptr);
PageSetSUI(metapg, ThisStartUpID); PageSetSUI(metapg, ThisStartUpID);
_bt_wrtbuf(rel, metabuf);
} }
END_CRIT_CODE; END_CRIT_CODE;
/* write and let go of the new root buffer */ /* write and let go of the new root buffer */
_bt_wrtbuf(rel, rootbuf); _bt_wrtbuf(rel, rootbuf);
_bt_wrtbuf(rel, metabuf);
/* update and release new sibling, and finally the old root */ /* update and release new sibling, and finally the old root */
_bt_wrtbuf(rel, rbuf); _bt_wrtbuf(rel, rbuf);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.43 2000/12/03 10:27:26 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.44 2000/12/28 13:00:07 vadim Exp $
* *
* NOTES * NOTES
* Postgres btree pages look like ordinary relation pages. The opaque * Postgres btree pages look like ordinary relation pages. The opaque
...@@ -167,6 +167,9 @@ _bt_getroot(Relation rel, int access) ...@@ -167,6 +167,9 @@ _bt_getroot(Relation rel, int access)
/* NO ELOG(ERROR) till meta is updated */ /* NO ELOG(ERROR) till meta is updated */
START_CRIT_CODE; START_CRIT_CODE;
metad->btm_root = rootblkno;
metad->btm_level = 1;
_bt_pageinit(rootpage, BufferGetPageSize(rootbuf)); _bt_pageinit(rootpage, BufferGetPageSize(rootbuf));
rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpage); rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpage);
rootopaque->btpo_flags |= (BTP_LEAF | BTP_ROOT); rootopaque->btpo_flags |= (BTP_LEAF | BTP_ROOT);
...@@ -175,22 +178,26 @@ _bt_getroot(Relation rel, int access) ...@@ -175,22 +178,26 @@ _bt_getroot(Relation rel, int access)
{ {
xl_btree_newroot xlrec; xl_btree_newroot xlrec;
XLogRecPtr recptr; XLogRecPtr recptr;
XLogRecData rdata;
xlrec.node = rel->rd_node; xlrec.node = rel->rd_node;
xlrec.level = 1;
BlockIdSet(&(xlrec.rootblk), rootblkno); BlockIdSet(&(xlrec.rootblk), rootblkno);
rdata.buffer = InvalidBuffer;
rdata.data = (char*)&xlrec;
rdata.len = SizeOfBtreeNewroot;
rdata.next = NULL;
recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_NEWROOT, recptr = XLogInsert(RM_BTREE_ID,
(char*)&xlrec, SizeOfBtreeNewroot, NULL, 0); XLOG_BTREE_NEWROOT|XLOG_BTREE_LEAF, &rdata);
PageSetLSN(rootpage, recptr); PageSetLSN(rootpage, recptr);
PageSetSUI(rootpage, ThisStartUpID); PageSetSUI(rootpage, ThisStartUpID);
PageSetLSN(metapg, recptr); PageSetLSN(metapg, recptr);
PageSetSUI(metapg, ThisStartUpID); PageSetSUI(metapg, ThisStartUpID);
} }
END_CRIT_CODE;
metad->btm_root = rootblkno; END_CRIT_CODE;
metad->btm_level = 1;
_bt_wrtnorelbuf(rel, rootbuf); _bt_wrtnorelbuf(rel, rootbuf);
...@@ -408,11 +415,21 @@ _bt_pagedel(Relation rel, ItemPointer tid) ...@@ -408,11 +415,21 @@ _bt_pagedel(Relation rel, ItemPointer tid)
{ {
xl_btree_delete xlrec; xl_btree_delete xlrec;
XLogRecPtr recptr; XLogRecPtr recptr;
XLogRecData rdata[2];
xlrec.target.node = rel->rd_node; xlrec.target.node = rel->rd_node;
xlrec.target.tid = *tid; xlrec.target.tid = *tid;
recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_DELETE, rdata[0].buffer = InvalidBuffer;
(char*) &xlrec, SizeOfBtreeDelete, NULL, 0); rdata[0].data = (char*)&xlrec;
rdata[0].len = SizeOfBtreeDelete;
rdata[0].next = &(rdata[1]);
rdata[1].buffer = buf;
rdata[1].data = NULL;
rdata[1].len = 0;
rdata[1].next = NULL;
recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_DELETE, rdata);
PageSetLSN(page, recptr); PageSetLSN(page, recptr);
PageSetSUI(page, ThisStartUpID); PageSetSUI(page, ThisStartUpID);
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.90 2000/12/22 00:51:53 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.91 2000/12/28 13:00:08 vadim Exp $
* *
* NOTES * NOTES
* Transaction aborts can now occur two ways: * Transaction aborts can now occur two ways:
...@@ -665,6 +665,7 @@ RecordTransactionCommit() ...@@ -665,6 +665,7 @@ RecordTransactionCommit()
if (MyLastRecPtr.xrecoff != 0) if (MyLastRecPtr.xrecoff != 0)
{ {
XLogRecData rdata;
xl_xact_commit xlrec; xl_xact_commit xlrec;
struct timeval delay; struct timeval delay;
XLogRecPtr recptr; XLogRecPtr recptr;
...@@ -672,12 +673,16 @@ RecordTransactionCommit() ...@@ -672,12 +673,16 @@ RecordTransactionCommit()
BufmgrCommit(); BufmgrCommit();
xlrec.xtime = time(NULL); xlrec.xtime = time(NULL);
rdata.buffer = InvalidBuffer;
rdata.data = (char *)(&xlrec);
rdata.len = SizeOfXactCommit;
rdata.next = NULL;
START_CRIT_CODE; START_CRIT_CODE;
/* /*
* SHOULD SAVE ARRAY OF RELFILENODE-s TO DROP * SHOULD SAVE ARRAY OF RELFILENODE-s TO DROP
*/ */
recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, &rdata);
(char*) &xlrec, SizeOfXactCommit, NULL, 0);
/* /*
* Sleep before commit! So we can flush more than one * Sleep before commit! So we can flush more than one
...@@ -785,13 +790,18 @@ RecordTransactionAbort(void) ...@@ -785,13 +790,18 @@ RecordTransactionAbort(void)
if (MyLastRecPtr.xrecoff != 0 && !TransactionIdDidCommit(xid)) if (MyLastRecPtr.xrecoff != 0 && !TransactionIdDidCommit(xid))
{ {
XLogRecData rdata;
xl_xact_abort xlrec; xl_xact_abort xlrec;
XLogRecPtr recptr; XLogRecPtr recptr;
xlrec.xtime = time(NULL); xlrec.xtime = time(NULL);
rdata.buffer = InvalidBuffer;
rdata.data = (char *)(&xlrec);
rdata.len = SizeOfXactAbort;
rdata.next = NULL;
START_CRIT_CODE; START_CRIT_CODE;
recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, &rdata);
(char*) &xlrec, SizeOfXactAbort, NULL, 0);
TransactionIdAbort(xid); TransactionIdAbort(xid);
MyProc->logRec.xrecoff = 0; MyProc->logRec.xrecoff = 0;
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.101 2000/11/25 20:33:51 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.102 2000/12/28 13:00:12 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -147,6 +147,8 @@ static MemoryContext nogc = NULL; /* special no-gc mem context */ ...@@ -147,6 +147,8 @@ static MemoryContext nogc = NULL; /* special no-gc mem context */
extern int optind; extern int optind;
extern char *optarg; extern char *optarg;
extern void SetRedoRecPtr(void);
/* /*
* At bootstrap time, we first declare all the indices to be built, and * At bootstrap time, we first declare all the indices to be built, and
* then build them. The IndexList structure stores enough information * then build them. The IndexList structure stores enough information
...@@ -349,6 +351,7 @@ BootstrapMain(int argc, char *argv[]) ...@@ -349,6 +351,7 @@ BootstrapMain(int argc, char *argv[])
{ {
CreateDummyCaches(); CreateDummyCaches();
CreateCheckPoint(false); CreateCheckPoint(false);
SetRedoRecPtr();
} }
else if (xlogop == BS_XLOG_STARTUP) else if (xlogop == BS_XLOG_STARTUP)
StartupXLOG(); StartupXLOG();
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.46 2000/12/08 20:10:19 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.47 2000/12/28 13:00:17 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -306,25 +306,38 @@ nextval(PG_FUNCTION_ARGS) ...@@ -306,25 +306,38 @@ nextval(PG_FUNCTION_ARGS)
{ {
xl_seq_rec xlrec; xl_seq_rec xlrec;
XLogRecPtr recptr; XLogRecPtr recptr;
XLogRecData rdata[2];
if (fetch) /* not all numbers were fetched */ Page page = BufferGetPage(buf);
log -= fetch;
xlrec.node = elm->rel->rd_node; xlrec.node = elm->rel->rd_node;
xlrec.value = next; rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char*)&xlrec;
rdata[0].len = sizeof(xl_seq_rec);
rdata[0].next = &(rdata[1]);
seq->last_value = next;
seq->is_called = 't';
seq->log_cnt = 0;
rdata[1].buffer = InvalidBuffer;
rdata[1].data = (char*)page + ((PageHeader) page)->pd_upper;
rdata[1].len = ((PageHeader)page)->pd_special -
((PageHeader)page)->pd_upper;
rdata[1].next = NULL;
recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG|XLOG_NO_TRAN, rdata);
recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG|XLOG_NO_TRAN, PageSetLSN(page, recptr);
(char*) &xlrec, sizeof(xlrec), NULL, 0); PageSetSUI(page, ThisStartUpID);
PageSetLSN(BufferGetPage(buf), recptr); if (fetch) /* not all numbers were fetched */
PageSetSUI(BufferGetPage(buf), ThisStartUpID); log -= fetch;
} }
/* save info in sequence relation */ /* update on-disk data */
seq->last_value = last; /* last fetched number */ seq->last_value = last; /* last fetched number */
seq->is_called = 't';
Assert(log >= 0); Assert(log >= 0);
seq->log_cnt = log; /* how much is logged */ seq->log_cnt = log; /* how much is logged */
seq->is_called = 't';
END_CRIT_CODE; END_CRIT_CODE;
LockBuffer(buf, BUFFER_LOCK_UNLOCK); LockBuffer(buf, BUFFER_LOCK_UNLOCK);
...@@ -385,25 +398,37 @@ do_setval(char *seqname, int32 next, bool iscalled) ...@@ -385,25 +398,37 @@ do_setval(char *seqname, int32 next, bool iscalled)
elm->last = next; /* last returned number */ elm->last = next; /* last returned number */
elm->cached = next; /* last cached number (forget cached values) */ elm->cached = next; /* last cached number (forget cached values) */
/* save info in sequence relation */
START_CRIT_CODE; START_CRIT_CODE;
seq->last_value = next; /* last fetched number */
seq->is_called = iscalled ? 't' : 'f';
seq->log_cnt = (iscalled) ? 0 : 1;
{ {
xl_seq_rec xlrec; xl_seq_rec xlrec;
XLogRecPtr recptr; XLogRecPtr recptr;
XLogRecData rdata[2];
Page page = BufferGetPage(buf);
xlrec.node = elm->rel->rd_node; xlrec.node = elm->rel->rd_node;
xlrec.value = next; rdata[0].buffer = InvalidBuffer;
rdata[0].data = (char*)&xlrec;
recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_SET|XLOG_NO_TRAN, rdata[0].len = sizeof(xl_seq_rec);
(char*) &xlrec, sizeof(xlrec), NULL, 0); rdata[0].next = &(rdata[1]);
PageSetLSN(BufferGetPage(buf), recptr); seq->last_value = next;
PageSetSUI(BufferGetPage(buf), ThisStartUpID); seq->is_called = 't';
seq->log_cnt = 0;
rdata[1].buffer = InvalidBuffer;
rdata[1].data = (char*)page + ((PageHeader) page)->pd_upper;
rdata[1].len = ((PageHeader)page)->pd_special -
((PageHeader)page)->pd_upper;
rdata[1].next = NULL;
recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG|XLOG_NO_TRAN, rdata);
PageSetLSN(page, recptr);
PageSetSUI(page, ThisStartUpID);
} }
/* save info in sequence relation */
seq->last_value = next; /* last fetched number */
seq->is_called = iscalled ? 't' : 'f';
seq->log_cnt = (iscalled) ? 0 : 1;
END_CRIT_CODE; END_CRIT_CODE;
LockBuffer(buf, BUFFER_LOCK_UNLOCK); LockBuffer(buf, BUFFER_LOCK_UNLOCK);
...@@ -708,50 +733,38 @@ get_param(DefElem *def) ...@@ -708,50 +733,38 @@ get_param(DefElem *def)
void seq_redo(XLogRecPtr lsn, XLogRecord *record) void seq_redo(XLogRecPtr lsn, XLogRecord *record)
{ {
uint8 info = record->xl_info & ~XLR_INFO_MASK; uint8 info = record->xl_info & ~XLR_INFO_MASK;
Relation reln; Relation reln;
Buffer buffer; Buffer buffer;
Page page; Page page;
ItemId lp; char *item;
HeapTupleData tuple; Size itemsz;
Form_pg_sequence seq; xl_seq_rec *xlrec = (xl_seq_rec*) XLogRecGetData(record);
xl_seq_rec *xlrec; sequence_magic *sm;
if (info != XLOG_SEQ_LOG && info != XLOG_SEQ_SET)
elog(STOP, "seq_redo: unknown op code %u", info);
xlrec = (xl_seq_rec*) XLogRecGetData(record); if (info != XLOG_SEQ_LOG)
elog(STOP, "seq_redo: unknown op code %u", info);
reln = XLogOpenRelation(true, RM_SEQ_ID, xlrec->node); reln = XLogOpenRelation(true, RM_SEQ_ID, xlrec->node);
if (!RelationIsValid(reln)) if (!RelationIsValid(reln))
return; return;
buffer = XLogReadBuffer(false, reln, 0); buffer = XLogReadBuffer(true, reln, 0);
if (!BufferIsValid(buffer)) if (!BufferIsValid(buffer))
elog(STOP, "seq_redo: can't read block of %u/%u", elog(STOP, "seq_redo: can't read block of %u/%u",
xlrec->node.tblNode, xlrec->node.relNode); xlrec->node.tblNode, xlrec->node.relNode);
page = (Page) BufferGetPage(buffer); page = (Page) BufferGetPage(buffer);
if (PageIsNew((PageHeader) page) ||
((sequence_magic *) PageGetSpecialPointer(page))->magic != SEQ_MAGIC)
elog(STOP, "seq_redo: uninitialized page of %u/%u",
xlrec->node.tblNode, xlrec->node.relNode);
if (XLByteLE(lsn, PageGetLSN(page)))
{
UnlockAndReleaseBuffer(buffer);
return;
}
lp = PageGetItemId(page, FirstOffsetNumber);
Assert(ItemIdIsUsed(lp));
tuple.t_data = (HeapTupleHeader) PageGetItem((Page) page, lp);
seq = (Form_pg_sequence) GETSTRUCT(&tuple); PageInit((Page) page, BufferGetPageSize(buffer), sizeof(sequence_magic));
sm = (sequence_magic *) PageGetSpecialPointer(page);
sm->magic = SEQ_MAGIC;
seq->last_value = xlrec->value; /* last logged value */ item = (char*)xlrec + sizeof(xl_seq_rec);
seq->is_called = 't'; itemsz = record->xl_len - sizeof(xl_seq_rec);
seq->log_cnt = 0; itemsz = MAXALIGN(itemsz);
if (PageAddItem(page, (Item)item, itemsz,
FirstOffsetNumber, LP_USED) == InvalidOffsetNumber)
PageSetLSN(page, lsn); PageSetLSN(page, lsn);
PageSetSUI(page, ThisStartUpID); PageSetSUI(page, ThisStartUpID);
...@@ -771,14 +784,12 @@ void seq_desc(char *buf, uint8 xl_info, char* rec) ...@@ -771,14 +784,12 @@ void seq_desc(char *buf, uint8 xl_info, char* rec)
if (info == XLOG_SEQ_LOG) if (info == XLOG_SEQ_LOG)
strcat(buf, "log: "); strcat(buf, "log: ");
else if (info == XLOG_SEQ_SET)
strcat(buf, "set: ");
else else
{ {
strcat(buf, "UNKNOWN"); strcat(buf, "UNKNOWN");
return; return;
} }
sprintf(buf + strlen(buf), "node %u/%u; value %d", sprintf(buf + strlen(buf), "node %u/%u",
xlrec->node.tblNode, xlrec->node.relNode, xlrec->value); xlrec->node.tblNode, xlrec->node.relNode);
} }
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.179 2000/12/22 23:12:05 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.180 2000/12/28 13:00:18 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -47,8 +47,10 @@ ...@@ -47,8 +47,10 @@
#include "utils/syscache.h" #include "utils/syscache.h"
#include "utils/temprel.h" #include "utils/temprel.h"
extern XLogRecPtr log_heap_clean(Relation reln, Buffer buffer);
extern XLogRecPtr log_heap_move(Relation reln, extern XLogRecPtr log_heap_move(Relation reln,
ItemPointerData from, HeapTuple newtup); Buffer oldbuf, ItemPointerData from,
Buffer newbuf, HeapTuple newtup);
static MemoryContext vac_context = NULL; static MemoryContext vac_context = NULL;
...@@ -65,7 +67,7 @@ static void vacuum_rel(Oid relid); ...@@ -65,7 +67,7 @@ static void vacuum_rel(Oid relid);
static void scan_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages, VacPageList fraged_pages); static void scan_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages, VacPageList fraged_pages);
static void repair_frag(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages, VacPageList fraged_pages, int nindices, Relation *Irel); static void repair_frag(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages, VacPageList fraged_pages, int nindices, Relation *Irel);
static void vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacpagelist); static void vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacpagelist);
static void vacuum_page(Page page, VacPage vacpage); static void vacuum_page(Relation onerel, Buffer buffer, VacPage vacpage);
static void vacuum_index(VacPageList vacpagelist, Relation indrel, int num_tuples, int keep_tuples); static void vacuum_index(VacPageList vacpagelist, Relation indrel, int num_tuples, int keep_tuples);
static void scan_index(Relation indrel, int num_tuples); static void scan_index(Relation indrel, int num_tuples);
static void update_relstats(Oid relid, int num_pages, int num_tuples, bool hasindex, VRelStats *vacrelstats); static void update_relstats(Oid relid, int num_pages, int num_tuples, bool hasindex, VRelStats *vacrelstats);
...@@ -1070,7 +1072,9 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, ...@@ -1070,7 +1072,9 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
if (last_vacuum_page->offsets_free > 0) /* there are dead tuples */ if (last_vacuum_page->offsets_free > 0) /* there are dead tuples */
{ /* on this page - clean */ { /* on this page - clean */
Assert(!isempty); Assert(!isempty);
vacuum_page(page, last_vacuum_page); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
vacuum_page(onerel, buf, last_vacuum_page);
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
dowrite = true; dowrite = true;
} }
else else
...@@ -1469,7 +1473,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, ...@@ -1469,7 +1473,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
int sv_offsets_used = destvacpage->offsets_used; int sv_offsets_used = destvacpage->offsets_used;
destvacpage->offsets_used = 0; destvacpage->offsets_used = 0;
vacuum_page(ToPage, destvacpage); vacuum_page(onerel, cur_buffer, destvacpage);
destvacpage->offsets_used = sv_offsets_used; destvacpage->offsets_used = sv_offsets_used;
} }
...@@ -1496,7 +1500,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, ...@@ -1496,7 +1500,8 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
{ {
XLogRecPtr recptr = XLogRecPtr recptr =
log_heap_move(onerel, tuple.t_self, &newtup); log_heap_move(onerel, Cbuf, tuple.t_self,
cur_buffer, &newtup);
if (Cbuf != cur_buffer) if (Cbuf != cur_buffer)
{ {
...@@ -1609,7 +1614,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, ...@@ -1609,7 +1614,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
ToPage = BufferGetPage(cur_buffer); ToPage = BufferGetPage(cur_buffer);
/* if this page was not used before - clean it */ /* if this page was not used before - clean it */
if (!PageIsEmpty(ToPage) && cur_page->offsets_used == 0) if (!PageIsEmpty(ToPage) && cur_page->offsets_used == 0)
vacuum_page(ToPage, cur_page); vacuum_page(onerel, cur_buffer, cur_page);
} }
else else
LockBuffer(cur_buffer, BUFFER_LOCK_EXCLUSIVE); LockBuffer(cur_buffer, BUFFER_LOCK_EXCLUSIVE);
...@@ -1661,7 +1666,8 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)" ...@@ -1661,7 +1666,8 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)"
{ {
XLogRecPtr recptr = XLogRecPtr recptr =
log_heap_move(onerel, tuple.t_self, &newtup); log_heap_move(onerel, buf, tuple.t_self,
cur_buffer, &newtup);
PageSetLSN(page, recptr); PageSetLSN(page, recptr);
PageSetSUI(page, ThisStartUpID); PageSetSUI(page, ThisStartUpID);
...@@ -1810,11 +1816,12 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)" ...@@ -1810,11 +1816,12 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)"
{ {
Assert((*curpage)->blkno < (BlockNumber) blkno); Assert((*curpage)->blkno < (BlockNumber) blkno);
buf = ReadBuffer(onerel, (*curpage)->blkno); buf = ReadBuffer(onerel, (*curpage)->blkno);
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
page = BufferGetPage(buf); page = BufferGetPage(buf);
if ((*curpage)->offsets_used == 0) /* this page was not used */ if ((*curpage)->offsets_used == 0) /* this page was not used */
{ {
if (!PageIsEmpty(page)) if (!PageIsEmpty(page))
vacuum_page(page, *curpage); vacuum_page(onerel, buf, *curpage);
} }
else else
/* this page was used */ /* this page was used */
...@@ -1848,6 +1855,7 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)" ...@@ -1848,6 +1855,7 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)"
Assert((*curpage)->offsets_used == num_tuples); Assert((*curpage)->offsets_used == num_tuples);
checked_moved += num_tuples; checked_moved += num_tuples;
} }
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
WriteBuffer(buf); WriteBuffer(buf);
} }
Assert(num_moved == checked_moved); Assert(num_moved == checked_moved);
...@@ -1891,6 +1899,8 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)" ...@@ -1891,6 +1899,8 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)"
vacpage->offsets_free > 0) vacpage->offsets_free > 0)
{ {
buf = ReadBuffer(onerel, vacpage->blkno); buf = ReadBuffer(onerel, vacpage->blkno);
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
START_CRIT_CODE;
page = BufferGetPage(buf); page = BufferGetPage(buf);
num_tuples = 0; num_tuples = 0;
for (offnum = FirstOffsetNumber; for (offnum = FirstOffsetNumber;
...@@ -1919,6 +1929,13 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)" ...@@ -1919,6 +1929,13 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)"
} }
Assert(vacpage->offsets_free == num_tuples); Assert(vacpage->offsets_free == num_tuples);
PageRepairFragmentation(page); PageRepairFragmentation(page);
{
XLogRecPtr recptr = log_heap_clean(onerel, buf);
PageSetLSN(page, recptr);
PageSetSUI(page, ThisStartUpID);
}
END_CRIT_CODE;
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
WriteBuffer(buf); WriteBuffer(buf);
} }
...@@ -1969,7 +1986,6 @@ static void ...@@ -1969,7 +1986,6 @@ static void
vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages) vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
{ {
Buffer buf; Buffer buf;
Page page;
VacPage *vacpage; VacPage *vacpage;
int nblocks; int nblocks;
int i; int i;
...@@ -1983,8 +1999,9 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages) ...@@ -1983,8 +1999,9 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
if ((*vacpage)->offsets_free > 0) if ((*vacpage)->offsets_free > 0)
{ {
buf = ReadBuffer(onerel, (*vacpage)->blkno); buf = ReadBuffer(onerel, (*vacpage)->blkno);
page = BufferGetPage(buf); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
vacuum_page(page, *vacpage); vacuum_page(onerel, buf, *vacpage);
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
WriteBuffer(buf); WriteBuffer(buf);
} }
} }
...@@ -2020,20 +2037,28 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages) ...@@ -2020,20 +2037,28 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
* and repair its fragmentation. * and repair its fragmentation.
*/ */
static void static void
vacuum_page(Page page, VacPage vacpage) vacuum_page(Relation onerel, Buffer buffer, VacPage vacpage)
{ {
Page page = BufferGetPage(buffer);
ItemId itemid; ItemId itemid;
int i; int i;
/* There shouldn't be any tuples moved onto the page yet! */ /* There shouldn't be any tuples moved onto the page yet! */
Assert(vacpage->offsets_used == 0); Assert(vacpage->offsets_used == 0);
START_CRIT_CODE;
for (i = 0; i < vacpage->offsets_free; i++) for (i = 0; i < vacpage->offsets_free; i++)
{ {
itemid = &(((PageHeader) page)->pd_linp[vacpage->offsets[i] - 1]); itemid = &(((PageHeader) page)->pd_linp[vacpage->offsets[i] - 1]);
itemid->lp_flags &= ~LP_USED; itemid->lp_flags &= ~LP_USED;
} }
PageRepairFragmentation(page); PageRepairFragmentation(page);
{
XLogRecPtr recptr = log_heap_clean(onerel, buffer);
PageSetLSN(page, recptr);
PageSetSUI(page, ThisStartUpID);
}
END_CRIT_CODE;
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.201 2000/12/20 21:51:52 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.202 2000/12/28 13:00:20 vadim Exp $
* *
* NOTES * NOTES
* *
...@@ -194,6 +194,8 @@ extern char *optarg; ...@@ -194,6 +194,8 @@ extern char *optarg;
extern int optind, extern int optind,
opterr; opterr;
extern void GetRedoRecPtr(void);
/* /*
* postmaster.c - function prototypes * postmaster.c - function prototypes
*/ */
...@@ -1533,6 +1535,7 @@ reaper(SIGNAL_ARGS) ...@@ -1533,6 +1535,7 @@ reaper(SIGNAL_ARGS)
/* /*
* Startup succeeded - remember its ID * Startup succeeded - remember its ID
* and RedoRecPtr
*/ */
SetThisStartUpID(); SetThisStartUpID();
...@@ -1633,7 +1636,10 @@ CleanupProc(int pid, ...@@ -1633,7 +1636,10 @@ CleanupProc(int pid,
{ {
CheckPointPID = 0; CheckPointPID = 0;
if (!FatalError) if (!FatalError)
{
checkpointed = time(NULL); checkpointed = time(NULL);
GetRedoRecPtr();
}
} }
else else
{ {
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.99 2000/12/22 20:04:43 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.100 2000/12/28 13:00:21 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2208,3 +2208,16 @@ MarkBufferForCleanup(Buffer buffer, void (*CleanupFunc)(Buffer)) ...@@ -2208,3 +2208,16 @@ MarkBufferForCleanup(Buffer buffer, void (*CleanupFunc)(Buffer))
SpinRelease(BufMgrLock); SpinRelease(BufMgrLock);
return; return;
} }
RelFileNode
BufferGetFileNode(Buffer buffer)
{
BufferDesc *bufHdr;
if (BufferIsLocal(buffer))
bufHdr = &(LocalBufferDescriptors[-buffer - 1]);
else
bufHdr = &BufferDescriptors[buffer - 1];
return(bufHdr->tag.rnode);
}
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.47 2000/11/12 20:51:52 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.48 2000/12/28 13:00:24 vadim Exp $
* *
* NOTES * NOTES
* Globals used all over the place should be declared here and not * Globals used all over the place should be declared here and not
...@@ -123,3 +123,49 @@ char *SharedSystemRelationNames[] = { ...@@ -123,3 +123,49 @@ char *SharedSystemRelationNames[] = {
VariableRelationName, VariableRelationName,
0 0
}; };
uint32 crc_table[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: htup.h,v 1.42 2000/12/27 23:59:13 tgl Exp $ * $Id: htup.h,v 1.43 2000/12/28 13:00:25 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -71,6 +71,13 @@ typedef HeapTupleHeaderData *HeapTupleHeader; ...@@ -71,6 +71,13 @@ typedef HeapTupleHeaderData *HeapTupleHeader;
#define XLOG_HEAP_DELETE 0x10 #define XLOG_HEAP_DELETE 0x10
#define XLOG_HEAP_UPDATE 0x20 #define XLOG_HEAP_UPDATE 0x20
#define XLOG_HEAP_MOVE 0x30 #define XLOG_HEAP_MOVE 0x30
#define XLOG_HEAP_CLEAN 0x40
#define XLOG_HEAP_OPMASK 0x70
/*
* When we insert 1st item on new page in INSERT/UPDATE
* we can (and we do) restore entire page in redo
*/
#define XLOG_HEAP_INIT_PAGE 0x80
/* /*
* All what we need to find changed tuple (18 bytes) * All what we need to find changed tuple (18 bytes)
...@@ -78,13 +85,10 @@ typedef HeapTupleHeaderData *HeapTupleHeader; ...@@ -78,13 +85,10 @@ typedef HeapTupleHeaderData *HeapTupleHeader;
typedef struct xl_heaptid typedef struct xl_heaptid
{ {
RelFileNode node; RelFileNode node;
CommandId cid; /* this is for "better" tuple' */
/* identification - it allows to avoid */
/* "compensation" records for undo */
ItemPointerData tid; /* changed tuple id */ ItemPointerData tid; /* changed tuple id */
} xl_heaptid; } xl_heaptid;
/* This is what we need to know about delete - ALIGN(18) = 24 bytes */ /* This is what we need to know about delete */
typedef struct xl_heap_delete typedef struct xl_heap_delete
{ {
xl_heaptid target; /* deleted tuple id */ xl_heaptid target; /* deleted tuple id */
...@@ -92,35 +96,44 @@ typedef struct xl_heap_delete ...@@ -92,35 +96,44 @@ typedef struct xl_heap_delete
#define SizeOfHeapDelete (offsetof(xl_heaptid, tid) + SizeOfIptrData) #define SizeOfHeapDelete (offsetof(xl_heaptid, tid) + SizeOfIptrData)
/* This is what we need to know about insert - 26 + data */ typedef struct xl_heap_header
typedef struct xl_heap_insert
{ {
xl_heaptid target; /* inserted tuple id */
/* something from tuple header */
int16 t_natts;
Oid t_oid; Oid t_oid;
int16 t_natts;
uint8 t_hoff; uint8 t_hoff;
uint8 mask; /* low 8 bits of t_infomask */ uint8 mask; /* low 8 bits of t_infomask */
/* TUPLE DATA FOLLOWS AT END OF STRUCT */ } xl_heap_header;
#define SizeOfHeapHeader (offsetof(xl_heap_header, mask) + sizeof(uint8))
/* This is what we need to know about insert */
typedef struct xl_heap_insert
{
xl_heaptid target; /* inserted tuple id */
/* xl_heap_header & TUPLE DATA FOLLOWS AT END OF STRUCT */
} xl_heap_insert; } xl_heap_insert;
#define SizeOfHeapInsert (offsetof(xl_heap_insert, mask) + sizeof(uint8)) #define SizeOfHeapInsert (offsetof(xl_heaptid, tid) + SizeOfIptrData)
/* This is what we need to know about update|move - 32|36 + data */ /* This is what we need to know about update|move */
typedef struct xl_heap_update typedef struct xl_heap_update
{ {
xl_heaptid target; /* deleted tuple id */ xl_heaptid target; /* deleted tuple id */
ItemPointerData newtid; /* new inserted tuple id */ ItemPointerData newtid; /* new inserted tuple id */
/* something from header of new tuple version */ /* NEW TUPLE xl_heap_header (XMIN & XMAX FOR MOVE OP) */
Oid t_oid; /* and TUPLE DATA FOLLOWS AT END OF STRUCT */
int16 t_natts;
uint8 t_hoff;
uint8 mask; /* low 8 bits of t_infomask */
/* NEW TUPLE DATA FOLLOWS AT END OF STRUCT */
/* (AFTER XMAX FOR MOVE OP) */
} xl_heap_update; } xl_heap_update;
#define SizeOfHeapUpdate (offsetof(xl_heap_update, mask) + sizeof(uint8)) #define SizeOfHeapUpdate (offsetof(xl_heap_update, newtid) + SizeOfIptrData)
/* This is what we need to know about page cleanup */
typedef struct xl_heap_clean
{
RelFileNode node;
BlockNumber block;
} xl_heap_clean;
#define SizeOfHeapClean (offsetof(xl_heap_clean, block) + sizeof(BlockNumber))
/* /*
* MaxTupleSize is the maximum allowed size of a tuple, including header and * MaxTupleSize is the maximum allowed size of a tuple, including header and
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: nbtree.h,v 1.48 2000/11/30 08:46:25 vadim Exp $ * $Id: nbtree.h,v 1.49 2000/12/28 13:00:25 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -217,8 +217,10 @@ typedef BTStackData *BTStack; ...@@ -217,8 +217,10 @@ typedef BTStackData *BTStack;
/* goes to the left sibling */ /* goes to the left sibling */
#define XLOG_BTREE_NEWROOT 0x40 /* new root page */ #define XLOG_BTREE_NEWROOT 0x40 /* new root page */
#define XLOG_BTREE_LEAF 0x80 /* leaf/internal page was changed */
/* /*
* All what we need to find changed index tuple (14 bytes) * All what we need to find changed index tuple
*/ */
typedef struct xl_btreetid typedef struct xl_btreetid
{ {
...@@ -227,7 +229,7 @@ typedef struct xl_btreetid ...@@ -227,7 +229,7 @@ typedef struct xl_btreetid
} xl_btreetid; } xl_btreetid;
/* /*
* This is what we need to know about delete - ALIGN(14) = 18 bytes. * This is what we need to know about delete
*/ */
typedef struct xl_btree_delete typedef struct xl_btree_delete
{ {
...@@ -237,39 +239,33 @@ typedef struct xl_btree_delete ...@@ -237,39 +239,33 @@ typedef struct xl_btree_delete
#define SizeOfBtreeDelete (offsetof(xl_btreetid, tid) + SizeOfIptrData) #define SizeOfBtreeDelete (offsetof(xl_btreetid, tid) + SizeOfIptrData)
/* /*
* This is what we need to know about pure (without split) insert - * This is what we need to know about pure (without split) insert
* 14 + [4+8] + btitem with key data. Note that we need in CommandID
* and HeapNode (4 + 8 bytes) only for leaf page insert.
*/ */
typedef struct xl_btree_insert typedef struct xl_btree_insert
{ {
xl_btreetid target; /* inserted tuple id */ xl_btreetid target; /* inserted tuple id */
/* [CommandID, HeapNode and ] BTITEM FOLLOWS AT END OF STRUCT */ /* BTITEM FOLLOWS AT END OF STRUCT */
} xl_btree_insert; } xl_btree_insert;
#define SizeOfBtreeInsert (offsetof(xl_btreetid, tid) + SizeOfIptrData) #define SizeOfBtreeInsert (offsetof(xl_btreetid, tid) + SizeOfIptrData)
/* /*
* This is what we need to know about insert with split - * On insert with split we save items of both left and right siblings
* 22 + {4 + 8 | left hi-key} + [btitem] + right sibling btitems. Note that * and restore content of both pages from log record
* we need in CommandID and HeapNode (4 + 8 bytes) for leaf pages
* and in left page hi-key for non-leaf ones.
*/ */
typedef struct xl_btree_split typedef struct xl_btree_split
{ {
xl_btreetid target; /* inserted tuple id */ xl_btreetid target; /* inserted tuple id */
BlockIdData otherblk; /* second block participated in split: */ BlockIdData otherblk; /* second block participated in split: */
/* first one is stored in target' tid */ /* first one is stored in target' tid */
BlockIdData parentblk; /* parent block */
BlockIdData leftblk; /* prev left block */
BlockIdData rightblk; /* next right block */ BlockIdData rightblk; /* next right block */
/* uint16 leftlen; /* len of left page items below */
* We log all btitems from the right sibling. If new btitem goes on /* LEFT AND RIGHT PAGES ITEMS FOLLOW AT THE END */
* the left sibling then we log it too and it will be the first
* BTItemData at the end of this struct after CommandId and HeapNode
* on the leaf pages and left page hi-key on non-leaf ones.
*/
} xl_btree_split; } xl_btree_split;
#define SizeOfBtreeSplit (offsetof(xl_btree_split, rightblk) + sizeof(BlockIdData)) #define SizeOfBtreeSplit (offsetof(xl_btree_split, leftlen) + sizeof(uint16))
/* /*
* New root log record. * New root log record.
...@@ -277,6 +273,7 @@ typedef struct xl_btree_split ...@@ -277,6 +273,7 @@ typedef struct xl_btree_split
typedef struct xl_btree_newroot typedef struct xl_btree_newroot
{ {
RelFileNode node; RelFileNode node;
int32 level;
BlockIdData rootblk; BlockIdData rootblk;
/* 0 or 2 BTITEMS FOLLOW AT END OF STRUCT */ /* 0 or 2 BTITEMS FOLLOW AT END OF STRUCT */
} xl_btree_newroot; } xl_btree_newroot;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* PostgreSQL transaction log manager * PostgreSQL transaction log manager
* *
* $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.14 2000/12/18 00:44:48 tgl Exp $ * $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.15 2000/12/28 13:00:25 vadim Exp $
*/ */
#ifndef XLOG_H #ifndef XLOG_H
#define XLOG_H #define XLOG_H
...@@ -13,12 +13,19 @@ ...@@ -13,12 +13,19 @@
#include "access/xlogdefs.h" #include "access/xlogdefs.h"
#include "access/xlogutils.h" #include "access/xlogutils.h"
typedef struct crc64
{
uint32 crc1;
uint32 crc2;
} crc64;
typedef struct XLogRecord typedef struct XLogRecord
{ {
crc64 xl_crc;
XLogRecPtr xl_prev; /* ptr to previous record in log */ XLogRecPtr xl_prev; /* ptr to previous record in log */
XLogRecPtr xl_xact_prev; /* ptr to previous record of this xact */ XLogRecPtr xl_xact_prev; /* ptr to previous record of this xact */
TransactionId xl_xid; /* xact id */ TransactionId xl_xid; /* xact id */
uint16 xl_len; /* len of record *data* on this page */ uint16 xl_len; /* total len of record *data* */
uint8 xl_info; uint8 xl_info;
RmgrId xl_rmid; /* resource manager inserted this record */ RmgrId xl_rmid; /* resource manager inserted this record */
...@@ -33,25 +40,30 @@ typedef struct XLogRecord ...@@ -33,25 +40,30 @@ typedef struct XLogRecord
((char*)record + SizeOfXLogRecord) ((char*)record + SizeOfXLogRecord)
/* /*
* When there is no space on current page we continue on the next * When there is no space on current page we continue
* page with subrecord. * on the next page with subrecord.
*/ */
typedef struct XLogSubRecord typedef struct XLogSubRecord
{ {
uint16 xl_len; uint16 xl_len; /* len of data left */
uint8 xl_info;
/* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */ /* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */
} XLogSubRecord; } XLogSubRecord;
#define SizeOfXLogSubRecord DOUBLEALIGN(sizeof(XLogSubRecord)) #define SizeOfXLogSubRecord DOUBLEALIGN(sizeof(XLogSubRecord))
/* /*
* XLOG uses only low 4 bits of xl_info. High 4 bits may be used * XLOG uses only low 4 bits of xl_info.
* by rmgr... * 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.
*/ */
#define XLR_TO_BE_CONTINUED 0x01 #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 #define XLR_INFO_MASK 0x0F
/* /*
...@@ -72,6 +84,7 @@ typedef struct XLogPageHeaderData ...@@ -72,6 +84,7 @@ typedef struct XLogPageHeaderData
typedef XLogPageHeaderData *XLogPageHeader; typedef XLogPageHeaderData *XLogPageHeader;
/* When record crosses page boundary */
#define XLP_FIRST_IS_SUBRECORD 0x0001 #define XLP_FIRST_IS_SUBRECORD 0x0001
#define XLByteLT(left, right) \ #define XLByteLT(left, right) \
...@@ -100,9 +113,22 @@ typedef struct RmgrData ...@@ -100,9 +113,22 @@ typedef struct RmgrData
extern RmgrData RmgrTable[]; extern RmgrData RmgrTable[];
extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info, /*
char *hdr, uint32 hdrlen, * List of these structs is used to pass data to XLOG.
char *buf, uint32 buflen); * 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).
*/
typedef struct XLogRecData
{
Buffer buffer; /* buffer associated with this data */
char *data;
uint32 len;
struct XLogRecData *next;
} XLogRecData;
extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata);
extern void XLogFlush(XLogRecPtr RecPtr); extern void XLogFlush(XLogRecPtr RecPtr);
extern void CreateCheckPoint(bool shutdown); extern void CreateCheckPoint(bool shutdown);
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: catversion.h,v 1.66 2000/12/03 14:51:09 thomas Exp $ * $Id: catversion.h,v 1.67 2000/12/28 13:00:27 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200012030 #define CATALOG_VERSION_NO 200012280
#endif #endif
...@@ -46,12 +46,11 @@ typedef FormData_pg_sequence *Form_pg_sequence; ...@@ -46,12 +46,11 @@ typedef FormData_pg_sequence *Form_pg_sequence;
/* XLOG stuff */ /* XLOG stuff */
#define XLOG_SEQ_LOG 0x00 #define XLOG_SEQ_LOG 0x00
#define XLOG_SEQ_SET 0x10
typedef struct xl_seq_rec typedef struct xl_seq_rec
{ {
RelFileNode node; RelFileNode node;
int4 value; /* last logged value */ /* SEQUENCE TUPLE DATA FOLLOWS AT THE END */
} xl_seq_rec; } xl_seq_rec;
extern Datum nextval(PG_FUNCTION_ARGS); extern Datum nextval(PG_FUNCTION_ARGS);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: bufmgr.h,v 1.47 2000/12/18 00:44:49 tgl Exp $ * $Id: bufmgr.h,v 1.48 2000/12/28 13:00:29 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -183,6 +183,7 @@ extern void DropBuffers(Oid dbid); ...@@ -183,6 +183,7 @@ extern void DropBuffers(Oid dbid);
extern void PrintPinnedBufs(void); extern void PrintPinnedBufs(void);
extern int BufferShmemSize(void); extern int BufferShmemSize(void);
extern int ReleaseBuffer(Buffer buffer); extern int ReleaseBuffer(Buffer buffer);
extern RelFileNode BufferGetFileNode(Buffer buffer);
extern void SetBufferCommitInfoNeedsSave(Buffer buffer); extern void SetBufferCommitInfoNeedsSave(Buffer buffer);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment