Commit b58c0411 authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

redo/undo support functions and cleanups.

parent e18a862d
This diff is collapsed.
......@@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.65 2000/10/13 12:05:20 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.66 2000/10/20 11:01:03 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1261,44 +1261,40 @@ _bt_del_item(Relation reln, Buffer buffer, BTItem btitem, bool insert,
}
lp = PageGetItemId(page, offno);
if (ItemIdDeleted(lp)) /* marked for deletion */
{
if (!InRecovery)
elog(STOP, "btree_%s_undo: deleted target tuple in rollback",
(insert) ? "insert" : "split");
}
else if (InRecovery) /* check heap tuple */
if (InRecovery) /* check heap tuple */
{
int result;
CommandId cid;
RelFileNode hnode;
Size hsize = (insert) ? SizeOfBtreeInsert : SizeOfBtreeSplit;
memcpy(&cid, (char*)xlrec + hsize, sizeof(CommandId));
memcpy(&hnode, (char*)xlrec + hsize + sizeof(CommandId), sizeof(RelFileNode));
result = XLogIsOwnerOfTuple(hnode, &(btitem->bti_itup.t_tid),
record->xl_xid, cid);
if (result < 0) /* not owner */
if (!ItemIdDeleted(lp))
{
UnlockAndReleaseBuffer(buffer);
return;
}
}
else if (! BufferIsUpdatable(buffer)) /* normal rollback */
{
lp->lp_flags |= LP_DELETE;
MarkBufferForCleanup(buffer, IndexPageCleanup);
return;
}
int result;
CommandId cid;
RelFileNode hnode;
Size hsize = (insert) ? SizeOfBtreeInsert : SizeOfBtreeSplit;
PageIndexTupleDelete(page, offno);
if (InRecovery)
{
memcpy(&cid, (char*)xlrec + hsize, sizeof(CommandId));
memcpy(&hnode, (char*)xlrec + hsize + sizeof(CommandId), sizeof(RelFileNode));
result = XLogIsOwnerOfTuple(hnode, &(btitem->bti_itup.t_tid),
record->xl_xid, cid);
if (result < 0) /* not owner */
{
UnlockAndReleaseBuffer(buffer);
return;
}
}
PageIndexTupleDelete(page, offno);
pageop = (BTPageOpaque) PageGetSpecialPointer(page);
pageop->btpo_flags |= BTP_REORDER;
UnlockAndWriteBuffer(buffer);
return;
}
UnlockAndWriteBuffer(buffer);
/* normal rollback */
if (ItemIdDeleted(lp)) /* marked for deletion ?! */
elog(STOP, "btree_%s_undo: deleted target tuple in rollback",
(insert) ? "insert" : "split");
lp->lp_flags |= LP_DELETE;
MarkBufferForCleanup(buffer, IndexPageCleanup);
return;
}
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.72 2000/10/11 21:28:17 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.73 2000/10/20 11:01:04 vadim Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
......@@ -154,6 +154,8 @@
*/
#include "postgres.h"
#include <sys/time.h>
#include "access/nbtree.h"
#include "catalog/heap.h"
#include "catalog/index.h"
......@@ -215,6 +217,19 @@ TransactionState CurrentTransactionState = &CurrentTransactionStateData;
int DefaultXactIsoLevel = XACT_READ_COMMITTED;
int XactIsoLevel;
#ifdef XLOG
#include "access/xlogutils.h"
int CommitDelay;
void xact_redo(XLogRecPtr lsn, XLogRecord *record);
void xact_undo(XLogRecPtr lsn, XLogRecord *record);
static void (*_RollbackFunc)(void*) = NULL;
static void *_RollbackData = NULL;
#endif
/* ----------------
* info returned when the system is disabled
*
......@@ -676,6 +691,28 @@ RecordTransactionCommit()
*/
TransactionIdCommit(xid);
#ifdef XLOG
{
xl_xact_commit xlrec;
struct timeval delay;
XLogRecPtr recptr;
xlrec.xtime = time(NULL);
/*
* MUST SAVE ARRAY OF RELFILENODE-s TO DROP
*/
recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT,
(char*) &xlrec, SizeOfXactCommit, NULL, 0);
/*
* Sleep before commit! So we can flush more than one
* commit records per single fsync.
*/
delay.tv_sec = 0;
delay.tv_usec = CommitDelay;
(void) select(0, NULL, NULL, NULL, &delay);
}
#endif
/*
* Now write the log info to the disk too.
*/
......@@ -785,6 +822,18 @@ RecordTransactionAbort()
if (SharedBufferChanged && !TransactionIdDidCommit(xid))
TransactionIdAbort(xid);
#ifdef XLOG
if (SharedBufferChanged)
{
xl_xact_abort xlrec;
XLogRecPtr recptr;
xlrec.xtime = time(NULL);
recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT,
(char*) &xlrec, SizeOfXactAbort, NULL, 0);
}
#endif
/*
* Tell bufmgr and smgr to release resources.
*/
......@@ -1123,10 +1172,13 @@ AbortTransaction()
AtEOXact_SPI();
AtEOXact_nbtree();
AtAbort_Cache();
AtAbort_Locks();
AtAbort_Memory();
AtEOXact_Files();
/* Here we'll rollback xaction changes */
AtAbort_Locks();
SharedBufferChanged = false; /* safest place to do it */
/* ----------------
......@@ -1663,3 +1715,54 @@ IsTransactionBlock()
return false;
}
#ifdef XLOG
void
xact_redo(XLogRecPtr lsn, XLogRecord *record)
{
uint8 info = record->xl_info & ~XLR_INFO_MASK;
if (info == XLOG_XACT_COMMIT)
{
xl_xact_commit *xlrec = (xl_xact_commit*) XLogRecGetData(record);
XLogMarkCommitted(record->xl_xid);
/* MUST REMOVE FILES OF ALL DROPPED RELATIONS */
}
else if (info == XLOG_XACT_ABORT)
{
XLogMarkAborted(record->xl_xid);
}
else
elog(STOP, "xact_redo: unknown op code %u", info);
}
void
xact_undo(XLogRecPtr lsn, XLogRecord *record)
{
uint8 info = record->xl_info & ~XLR_INFO_MASK;
if (info == XLOG_XACT_COMMIT) /* shouldn't be called by XLOG */
elog(STOP, "xact_undo: can't undo committed xaction");
else if (info != XLOG_XACT_ABORT)
elog(STOP, "xact_redo: unknown op code %u", info);
}
void
XactPushRollback(void (*func) (void *), void* data)
{
if (_RollbackFunc != NULL)
elog(STOP, "XactPushRollback: already installed");
_RollbackFunc = func;
_RollbackData = data;
}
void
XactPopRollback(void)
{
_RollbackFunc = NULL;
}
#endif
......@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.17 2000/07/04 01:49:43 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.18 2000/10/20 11:01:04 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -40,6 +40,7 @@ char ControlFilePath[MAXPGPATH];
uint32 XLOGbuffers = 0;
XLogRecPtr MyLastRecPtr = {0, 0};
bool StopIfError = false;
bool InRecovery = false;
SPINLOCK ControlFileLockId;
SPINLOCK XidGenLockId;
......@@ -163,17 +164,6 @@ typedef struct CheckPoint
#define NextBufIdx(curridx) \
((curridx == XLogCtl->XLogCacheBlck) ? 0 : (curridx + 1))
#define XLByteLT(left, right) \
(right.xlogid > left.xlogid || \
(right.xlogid == left.xlogid && right.xrecoff > left.xrecoff))
#define XLByteLE(left, right) \
(right.xlogid > left.xlogid || \
(right.xlogid == left.xlogid && right.xrecoff >= left.xrecoff))
#define XLByteEQ(left, right) \
(right.xlogid == left.xlogid && right.xrecoff == left.xrecoff)
#define InitXLBuffer(curridx) (\
XLogCtl->xlblocks[curridx].xrecoff = \
(XLogCtl->xlblocks[Insert->curridx].xrecoff == XLogFileSize) ? \
......
/*-------------------------------------------------------------------------
*
* xlog.c
* xlogutils.c
*
*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
......@@ -9,12 +9,26 @@
*-------------------------------------------------------------------------
*/
#ifdef XLOG
#include "postgres.h"
#include "access/xlog.h"
#include "access/xact.h"
#include "storage/bufpage.h"
#include "storage/bufmgr.h"
#include "storage/smgr.h"
#include "access/htup.h"
#include "access/xlogutils.h"
#include "catalog/pg_database.h"
#ifdef XLOG
/*
* ---------------------------------------------------------------
*
* Index support functions
*
*----------------------------------------------------------------
*/
/*
* Check if specified heap tuple was inserted by given
......@@ -59,7 +73,8 @@ XLogIsOwnerOfTuple(RelFileNode hnode, ItemPointer iptr,
htup = (HeapTupleHeader) PageGetItem(page, lp);
if (PageGetSUI(page) != ThisStartUpID || htup->t_xmin != xid || htup->t_cmin != cid)
Assert(PageGetSUI(page) == ThisStartUpID);
if (htup->t_xmin != xid || htup->t_cmin != cid)
{
UnlockAndReleaseBuffer(buffer);
return(-1);
......@@ -70,6 +85,8 @@ XLogIsOwnerOfTuple(RelFileNode hnode, ItemPointer iptr,
}
/*
* MUST BE CALLED ONLY ON RECOVERY.
*
* Check if exists valid (inserted by not aborted xaction) heap tuple
* for given item pointer
*/
......@@ -98,6 +115,14 @@ XLogIsValidTuple(RelFileNode hnode, ItemPointer iptr)
UnlockAndReleaseBuffer(buffer);
return(false);
}
if (PageGetSUI(page) != ThisStartUpID)
{
Assert(PageGetSUI(page) < ThisStartUpID);
UnlockAndReleaseBuffer(buffer);
return(true);
}
lp = PageGetItemId(page, ItemPointerGetOffsetNumber(iptr));
if (!ItemIdIsUsed(lp) || ItemIdDeleted(lp))
{
......@@ -107,7 +132,9 @@ XLogIsValidTuple(RelFileNode hnode, ItemPointer iptr)
htup = (HeapTupleHeader) PageGetItem(page, lp);
if (XLogIsAborted(PageGetSUI(page), htup->t_xmin))
/* MUST CHECK WASN'T TUPLE INSERTED IN PREV STARTUP */
if (XLogIsAborted(htup->t_xmin))
{
UnlockAndReleaseBuffer(buffer);
return(false);
......@@ -117,4 +144,257 @@ XLogIsValidTuple(RelFileNode hnode, ItemPointer iptr)
return(true);
}
/*
* ---------------------------------------------------------------
*
* Transaction support functions for recovery
*
* On recovery we create tmp file to know what xactions were
* committed/aborted (2 bits per xaction).
*
*----------------------------------------------------------------
*/
bool
XLogIsAborted(TransactionId xid)
{
return(false);
}
bool
XLogIsCommitted(TransactionId xid)
{
return(true);
}
void
XLogMarkAborted(TransactionId xid)
{
return;
}
void
XLogMarkCommitted(TransactionId xid)
{
return;
}
/*
* ---------------------------------------------------------------
*
* Storage related support functions
*
*----------------------------------------------------------------
*/
Buffer
XLogReadBuffer(bool extend, Relation reln, BlockNumber blkno)
{
BlockNumber lastblock = RelationGetNumberOfBlocks(reln);
Buffer buffer;
if (blkno >= lastblock)
{
buffer = InvalidBuffer;
if (extend) /* we do this in recovery only - no locks */
{
Assert(InRecovery);
while (lastblock <= blkno)
{
buffer = ReadBuffer(reln, P_NEW);
lastblock++;
}
}
if (buffer != InvalidBuffer)
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
return(buffer);
}
buffer = ReadBuffer(reln, blkno);
if (buffer != InvalidBuffer)
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
return(buffer);
}
/*
* "Relation" cache
*/
typedef struct XLogRelDesc
{
RelationData reldata;
struct XLogRelDesc *lessRecently;
struct XLogRelDesc *moreRecently;
} XLogRelDesc;
typedef struct XLogRelCacheEntry
{
RelFileNode rnode;
XLogRelDesc *rdesc;
} XLogRelCacheEntry;
static HTAB *_xlrelcache;
static XLogRelDesc *_xlrelarr = NULL;
static Form_pg_class _xlpgcarr = NULL;
static int _xlast = 0;
static int _xlcnt = 0;
#define _XLOG_INITRELCACHESIZE 32
#define _XLOG_MAXRELCACHESIZE 512
void
XLogCloseRelationCache(void)
{
int i;
if (!_xlrelarr)
return;
for (i = 1; i < _xlast; i++)
{
Relation reln = &(_xlrelarr[i].reldata);
if (reln->rd_fd >= 0)
smgrclose(DEFAULT_SMGR, reln);
}
free(_xlrelarr);
free(_xlpgcarr);
hash_destroy(_xlrelcache);
_xlrelarr = NULL;
}
static void
_xl_init_rel_cache(void)
{
HASHCTL ctl;
_xlcnt = _XLOG_INITRELCACHESIZE;
_xlast = 0;
_xlrelarr = (XLogRelDesc*) malloc(sizeof(XLogRelDesc) * _xlcnt);
memset(_xlrelarr, 0, sizeof(XLogRelDesc) * _xlcnt);
_xlpgcarr = (Form_pg_class) malloc(sizeof(FormData_pg_class) * _xlcnt);
memset(_xlpgcarr, 0, sizeof(XLogRelDesc) * _xlcnt);
memset(&ctl, 0, (int) sizeof(ctl));
ctl.keysize = sizeof(RelFileNode);
ctl.datasize = sizeof(XLogRelDesc*);
ctl.hash = tag_hash;
_xlrelcache = hash_create(_XLOG_INITRELCACHESIZE, &ctl,
HASH_ELEM | HASH_FUNCTION);
}
static XLogRelDesc*
_xl_new_reldesc(void)
{
_xlast++;
if (_xlast < _xlcnt)
{
_xlrelarr[_xlast].reldata.rd_rel = &(_xlpgcarr[_xlast]);
return(&(_xlrelarr[_xlast]));
}
if ( 2 * _xlcnt <= _XLOG_MAXRELCACHESIZE)
{
_xlrelarr = (XLogRelDesc*) realloc(_xlrelarr,
2 * sizeof(XLogRelDesc) * _xlcnt);
memset(&(_xlrelarr[_xlcnt]), 0, sizeof(XLogRelDesc) * _xlcnt);
_xlpgcarr = (Form_pg_class) realloc(_xlpgcarr,
2 * sizeof(FormData_pg_class) * _xlcnt);
memset(&(_xlpgcarr[_xlcnt]), 0, sizeof(FormData_pg_class) * _xlcnt);
_xlcnt += _xlcnt;
_xlrelarr[_xlast].reldata.rd_rel = &(_xlpgcarr[_xlast]);
return(&(_xlrelarr[_xlast]));
}
else /* reuse */
{
XLogRelCacheEntry *hentry;
bool found;
XLogRelDesc *res = _xlrelarr[0].moreRecently;
Form_pg_class tpgc = res->reldata.rd_rel;
res->lessRecently->moreRecently = res->moreRecently;
res->moreRecently->lessRecently = res->lessRecently;
hentry = (XLogRelCacheEntry*) hash_search(_xlrelcache,
(char*)&(res->reldata.rd_node), HASH_REMOVE, &found);
if (hentry == NULL)
elog(STOP, "XLogOpenRelation: can't delete from cache");
if (!found)
elog(STOP, "XLogOpenRelation: file was not found in cache");
if (res->reldata.rd_fd >= 0)
smgrclose(DEFAULT_SMGR, &(res->reldata));
memset(res, 0, sizeof(XLogRelDesc));
memset(tpgc, 0, sizeof(FormData_pg_class));
res->reldata.rd_rel = tpgc;
_xlast--;
return(res);
}
}
Relation
XLogOpenRelation(bool redo, RmgrId rmid, RelFileNode rnode)
{
XLogRelDesc *res;
XLogRelCacheEntry *hentry;
bool found;
if (!_xlrelarr)
_xl_init_rel_cache();
hentry = (XLogRelCacheEntry*)
hash_search(_xlrelcache, (char*)&rnode, HASH_FIND, &found);
if (hentry == NULL)
elog(STOP, "XLogOpenRelation: error in cache");
if (found)
{
res = hentry->rdesc;
res->lessRecently->moreRecently = res->moreRecently;
res->moreRecently->lessRecently = res->lessRecently;
}
else
{
res = _xl_new_reldesc();
sprintf(RelationGetPhysicalRelationName(&(res->reldata)), "%u", rnode.relNode);
/* unexisting DB id */
res->reldata.rd_lockInfo.lockRelId.dbId = RecoveryDb;
res->reldata.rd_lockInfo.lockRelId.relId = rnode.relNode;
res->reldata.rd_node = rnode;
hentry = (XLogRelCacheEntry*)
hash_search(_xlrelcache, (char*)&rnode, HASH_ENTER, &found);
if (hentry == NULL)
elog(STOP, "XLogOpenRelation: can't insert into cache");
if (found)
elog(STOP, "XLogOpenRelation: file found on insert into cache");
hentry->rdesc = res;
res->reldata.rd_unlinked = true; /* look smgropen */
res->reldata.rd_fd = smgropen(DEFAULT_SMGR, &(res->reldata));
}
res->moreRecently = &(_xlrelarr[0]);
res->lessRecently = _xlrelarr[0].lessRecently;
_xlrelarr[0].lessRecently = res;
res->lessRecently->moreRecently = res;
if (res->reldata.rd_fd < 0) /* file doesn't exist */
return(NULL);
return(&(res->reldata));
}
#endif
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.87 2000/10/18 05:50:15 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.88 2000/10/20 11:01:07 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -2481,3 +2481,56 @@ AbortBufferIO(void)
SpinRelease(BufMgrLock);
}
}
/*
* Cleanup buffer or mark it for cleanup. Buffer may be cleaned
* up if it's pinned only once.
*
* NOTE: buffer must be excl locked.
*/
void
MarkBufferForCleanup(Buffer buffer, void (*CleanupFunc)(Buffer))
{
BufferDesc *bufHdr = &BufferDescriptors[buffer - 1];
Assert(PrivateRefCount[buffer - 1] > 0);
if (PrivateRefCount[buffer - 1] > 1)
{
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
PrivateRefCount[buffer - 1]--;
SpinAcquire(BufMgrLock);
Assert(bufHdr->refcount > 0);
bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
bufHdr->CleanupFunc = CleanupFunc;
SpinRelease(BufMgrLock);
return;
}
SpinAcquire(BufMgrLock);
Assert(bufHdr->refcount > 0);
if (bufHdr->refcount == 1)
{
SpinRelease(BufMgrLock);
CleanupFunc(buffer);
CleanupFunc = NULL;
}
else
SpinRelease(BufMgrLock);
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
PrivateRefCount[buffer - 1]--;
SpinAcquire(BufMgrLock);
Assert(bufHdr->refcount > 0);
bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
bufHdr->CleanupFunc = CleanupFunc;
bufHdr->refcount--;
if (bufHdr->refcount == 0)
{
AddBufferToFreelist(bufHdr);
bufHdr->flags |= BM_FREE;
}
SpinRelease(BufMgrLock);
return;
}
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.75 2000/10/16 14:52:12 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.76 2000/10/20 11:01:11 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -875,12 +875,6 @@ mdtruncate(Relation reln, int nblocks)
int
mdcommit()
{
#ifdef XLOG
sync();
sleep(1);
sync();
return SM_SUCCESS;
#else
int i;
MdfdVec *v;
......@@ -902,7 +896,6 @@ mdcommit()
}
return SM_SUCCESS;
#endif /* XLOG */
}
/*
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: htup.h,v 1.35 2000/09/07 09:58:35 vadim Exp $
* $Id: htup.h,v 1.36 2000/10/20 11:01:14 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -95,7 +95,7 @@ typedef struct xl_heap_delete
xl_heaptid target; /* deleted tuple id */
} 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_insert
......@@ -111,12 +111,13 @@ typedef struct xl_heap_insert
#define SizeOfHeapInsert (offsetof(xl_heap_insert, mask) + sizeof(uint8))
/* This is what we need to know about update - 28 + data */
/* This is what we need to know about update - 32 + data */
typedef struct xl_heap_update
{
xl_heaptid target; /* deleted tuple id */
ItemPointerData newtid; /* new inserted tuple id */
/* something from header of new tuple version */
Oid t_oid;
int16 t_natts;
uint8 t_hoff;
uint8 mask; /* low 8 bits of t_infomask */
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: xact.h,v 1.27 2000/07/28 01:04:40 tgl Exp $
* $Id: xact.h,v 1.28 2000/10/20 11:01:14 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -78,6 +78,35 @@ typedef TransactionStateData *TransactionState;
(*((TransactionId*) (dest)) = NullTransactionId)
#ifdef XLOG
/*
* XLOG allows to store some information in high 4 bits of log
* record xl_info field
*/
#define XLOG_XACT_COMMIT 0x00
#define XLOG_XACT_ABORT 0x20
typedef struct xl_xact_commit
{
time_t xtime;
/*
* Array of RelFileNode-s to drop may follow
* at the end of struct
*/
} xl_xact_commit;
#define SizeOfXactCommit ((offsetof(xl_xact_commit, xtime) + sizeof(time_t)))
typedef struct xl_xact_abort
{
time_t xtime;
} xl_xact_abort;
#define SizeOfXactAbort ((offsetof(xl_xact_abort, xtime) + sizeof(time_t)))
#endif
/* ----------------
* extern definitions
* ----------------
......@@ -108,6 +137,9 @@ extern void AbortOutOfAnyTransaction(void);
extern TransactionId DisabledTransactionId;
extern void XactPushRollback(void (*func) (void *), void* data);
extern void XactPopRollback(void);
/* defined in xid.c */
extern Datum xidin(PG_FUNCTION_ARGS);
extern Datum xidout(PG_FUNCTION_ARGS);
......
......@@ -72,12 +72,24 @@ typedef XLogPageHeaderData *XLogPageHeader;
#define XLP_FIRST_IS_SUBRECORD 0x0001
#define XLByteLT(left, right) \
(right.xlogid > left.xlogid || \
(right.xlogid == left.xlogid && right.xrecoff > left.xrecoff))
#define XLByteLE(left, right) \
(right.xlogid > left.xlogid || \
(right.xlogid == left.xlogid && right.xrecoff >= left.xrecoff))
#define XLByteEQ(left, right) \
(right.xlogid == left.xlogid && right.xrecoff == left.xrecoff)
/*
* StartUpID (SUI) - system startups counter.
* It's to allow removing pg_log after shutdown.
*/
typedef uint32 StartUpID;
extern StartUpID ThisStartUpID;
extern bool InRecovery;
extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info,
char *hdr, uint32 hdrlen,
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_database.h,v 1.10 2000/10/16 14:52:26 vadim Exp $
* $Id: pg_database.h,v 1.11 2000/10/20 11:01:17 vadim Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -61,4 +61,12 @@ DESCR("");
#define TemplateDbOid 1
/* Just to mark OID as used for unused_oid script -:) */
#define DATAMARKOID(x)
DATAMARKOID( = 2)
#define RecoveryDb 2
#undef DATAMARKOID
#endif /* PG_DATABASE_H */
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: buf_internals.h,v 1.39 2000/10/18 05:50:16 vadim Exp $
* $Id: buf_internals.h,v 1.40 2000/10/20 11:01:21 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -121,10 +121,19 @@ typedef struct sbufdesc
*
* Why we keep relId here? To re-use file descriptors. On rollback
* WAL uses dummy relId - bad (more blind writes - open/close calls),
* but allowable. Obviously we should have another cache in file manager.
* but allowable. Obviously we should have another cache in file manager
* - fd is not relcache deal.
*/
LockRelId relId;
BufferBlindId blind; /* was used to support blind write */
/*
* When we can't delete item from page (someone else has buffer pinned)
* we mark buffer for cleanup by specifying appropriate for buffer
* content cleanup function. Buffer will be cleaned up from release
* buffer functions.
*/
void (*CleanupFunc)(Buffer);
} BufferDesc;
/*
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: bufmgr.h,v 1.40 2000/08/07 20:15:50 tgl Exp $
* $Id: bufmgr.h,v 1.41 2000/10/20 11:01:21 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -44,6 +44,17 @@ extern int ShowPinTrace;
#define BUFFER_LOCK_SHARE 1
#define BUFFER_LOCK_EXCLUSIVE 2
#define UnlockAndReleaseBuffer(buffer) \
( \
LockBuffer(buffer, BUFFER_LOCK_UNLOCK), \
ReleaseBuffer(buffer) \
)
#define UnlockAndWriteBuffer(buffer) \
( \
LockBuffer(buffer, BUFFER_LOCK_UNLOCK), \
WriteBuffer(buffer) \
)
/*
* BufferIsValid
......@@ -163,4 +174,7 @@ extern void UnlockBuffers(void);
extern void LockBuffer(Buffer buffer, int mode);
extern void AbortBufferIO(void);
extern bool BufferIsUpdatable(Buffer buffer);
extern void MarkBufferForCleanup(Buffer buffer, void (*CleanupFunc)(Buffer));
#endif
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: bufpage.h,v 1.32 2000/09/07 09:58:36 vadim Exp $
* $Id: bufpage.h,v 1.33 2000/10/20 11:01:21 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -20,6 +20,7 @@
#include "storage/itemid.h"
#include "storage/off.h"
#include "storage/page.h"
#include "access/xlog.h"
/*
* a postgres disk page is an abstraction layered on top of a postgres
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: itemid.h,v 1.12 2000/09/07 09:58:36 vadim Exp $
* $Id: itemid.h,v 1.13 2000/10/20 11:01:21 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -40,6 +40,12 @@ typedef ItemIdData *ItemId;
#endif
/*
* This bit may be passed to PageAddItem together with
* LP_USED & LP_DELETED bits to specify overwrite mode
*/
#define OverwritePageMode 0x10
/*
* Item offsets, lengths, and flags are represented by these types when
* they're not actually stored in an ItemIdData.
......
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