mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-06 15:24:56 +08:00
heap' xlog records
This commit is contained in:
parent
664dd614d9
commit
bf1c8f2b3b
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.69 2000/05/30 00:49:39 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.70 2000/06/02 10:20:24 vadim Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
@ -1246,6 +1246,27 @@ heap_insert(Relation relation, HeapTuple tup)
|
||||
|
||||
RelationPutHeapTupleAtEnd(relation, tup);
|
||||
|
||||
#ifdef XLOG
|
||||
/* XLOG stuff */
|
||||
{
|
||||
xl_heap_insert xlrec;
|
||||
xlrec.itid.dbId = relation->rd_lockInfo.lockRelId.dbId;
|
||||
xlrec.itid.relId = relation->rd_lockInfo.lockRelId.relId;
|
||||
XXX xlrec.itid.tid = tp.t_self;
|
||||
xlrec.t_natts = tup->t_data->t_natts;
|
||||
xlrec.t_oid = tup->t_data->t_oid;
|
||||
xlrec.t_hoff = tup->t_data->t_hoff;
|
||||
xlrec.mask = tup->t_data->t_infomask;
|
||||
|
||||
XLogRecPtr recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_INSERT,
|
||||
(char*) xlrec, sizeof(xlrec),
|
||||
(char*) tup->t_data + offsetof(HeapTupleHeaderData, tbits),
|
||||
tup->t_len - offsetof(HeapTupleHeaderData, tbits));
|
||||
|
||||
dp->pd_lsn = recptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsSystemRelationName(RelationGetRelationName(relation)))
|
||||
RelationMark4RollbackHeapTuple(relation, tup);
|
||||
|
||||
@ -1333,6 +1354,20 @@ l1:
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef XLOG
|
||||
/* XLOG stuff */
|
||||
{
|
||||
xl_heap_delete xlrec;
|
||||
xlrec.dtid.dbId = relation->rd_lockInfo.lockRelId.dbId;
|
||||
xlrec.dtid.relId = relation->rd_lockInfo.lockRelId.relId;
|
||||
xlrec.dtid.tid = tp.t_self;
|
||||
XLogRecPtr recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE,
|
||||
(char*) xlrec, sizeof(xlrec), NULL, 0);
|
||||
|
||||
dp->pd_lsn = recptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* store transaction information of xact deleting the tuple */
|
||||
TransactionIdStore(GetCurrentTransactionId(), &(tp.t_data->t_xmax));
|
||||
tp.t_data->t_cmax = GetCurrentCommandId();
|
||||
|
@ -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.14 2000/06/02 03:58:34 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.15 2000/06/02 10:20:25 vadim Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -219,7 +219,7 @@ static char readBuf[BLCKSZ];
|
||||
static XLogRecord *nextRecord = NULL;
|
||||
|
||||
XLogRecPtr
|
||||
XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen)
|
||||
XLogInsert(RmgrId rmid, uint8 info, char *hdr, uint32 hdrlen, char *buf, uint32 buflen)
|
||||
{
|
||||
XLogCtlInsert *Insert = &XLogCtl->Insert;
|
||||
XLogRecord *record;
|
||||
@ -231,6 +231,7 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen)
|
||||
uint16 curridx;
|
||||
bool updrqst = false;
|
||||
|
||||
Assert(!(info & XLR_INFO_MASK));
|
||||
if (len == 0 || len > MAXLOGRECSZ)
|
||||
elog(STOP, "XLogInsert: invalid record len %u", len);
|
||||
|
||||
@ -306,7 +307,8 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen)
|
||||
}
|
||||
record->xl_xid = GetCurrentTransactionId();
|
||||
record->xl_len = (len > freespace) ? freespace : len;
|
||||
record->xl_info = (len > freespace) ? XLR_TO_BE_CONTINUED : 0;
|
||||
record->xl_info = (len > freespace) ?
|
||||
(info | XLR_TO_BE_CONTINUED) : info;
|
||||
record->xl_rmid = rmid;
|
||||
RecPtr.xlogid = XLogCtl->xlblocks[curridx].xlogid;
|
||||
RecPtr.xrecoff =
|
||||
@ -318,8 +320,7 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen)
|
||||
MyProc->logRec = RecPtr;
|
||||
SpinRelease(SInvalLock);
|
||||
}
|
||||
MyLastRecPtr = RecPtr;
|
||||
RecPtr.xrecoff += record->xl_len;
|
||||
MyLastRecPtr = RecPtr; /* begin of record */
|
||||
Insert->currpos += SizeOfXLogRecord;
|
||||
if (freespace > 0)
|
||||
{
|
||||
@ -364,6 +365,7 @@ nbuf:
|
||||
if (hdrlen > freespace)
|
||||
{
|
||||
subrecord->xl_len = freespace;
|
||||
/* we don't store info in subrecord' xl_info */
|
||||
subrecord->xl_info = XLR_TO_BE_CONTINUED;
|
||||
memcpy(Insert->currpos, hdr, freespace);
|
||||
hdrlen -= freespace;
|
||||
@ -383,6 +385,7 @@ nbuf:
|
||||
if (buflen > freespace)
|
||||
{
|
||||
subrecord->xl_len += freespace;
|
||||
/* we don't store info in subrecord' xl_info */
|
||||
subrecord->xl_info = XLR_TO_BE_CONTINUED;
|
||||
memcpy(Insert->currpos, buf, freespace);
|
||||
buflen -= freespace;
|
||||
@ -395,15 +398,22 @@ nbuf:
|
||||
memcpy(Insert->currpos, buf, buflen);
|
||||
Insert->currpos += buflen;
|
||||
}
|
||||
/* we don't store info in subrecord' xl_info */
|
||||
subrecord->xl_info = 0;
|
||||
RecPtr.xlogid = XLogCtl->xlblocks[curridx].xlogid;
|
||||
RecPtr.xrecoff = XLogCtl->xlblocks[curridx].xrecoff -
|
||||
BLCKSZ + SizeOfXLogPHD + subrecord->xl_len;
|
||||
Insert->currpos = ((char *) Insert->currpage) +
|
||||
DOUBLEALIGN(Insert->currpos - ((char *) Insert->currpage));
|
||||
}
|
||||
freespace = ((char *) Insert->currpage) + BLCKSZ - Insert->currpos;
|
||||
|
||||
/*
|
||||
* Begin of the next record will be stored as LSN for
|
||||
* changed data page...
|
||||
*/
|
||||
RecPtr.xlogid = XLogCtl->xlblocks[curridx].xlogid;
|
||||
RecPtr.xrecoff =
|
||||
XLogCtl->xlblocks[curridx].xrecoff - BLCKSZ +
|
||||
Insert->currpos - ((char *) Insert->currpage);
|
||||
|
||||
/*
|
||||
* All done! Update global LgwrRqst if some block was filled up.
|
||||
*/
|
||||
@ -884,7 +894,8 @@ got_record:;
|
||||
XLogSubRecord *subrecord;
|
||||
uint32 len = record->xl_len;
|
||||
|
||||
if (record->xl_len + RecPtr->xrecoff % BLCKSZ + SizeOfXLogRecord != BLCKSZ)
|
||||
if (DOUBLEALIGN(record->xl_len) + RecPtr->xrecoff % BLCKSZ +
|
||||
SizeOfXLogRecord != BLCKSZ)
|
||||
{
|
||||
elog(emode, "ReadRecord: invalid fragmented record len %u in (%u, %u)",
|
||||
record->xl_len, RecPtr->xlogid, RecPtr->xrecoff);
|
||||
@ -945,7 +956,7 @@ got_record:;
|
||||
buffer += subrecord->xl_len;
|
||||
if (subrecord->xl_info & XLR_TO_BE_CONTINUED)
|
||||
{
|
||||
if (subrecord->xl_len +
|
||||
if (DOUBLEALIGN(subrecord->xl_len) +
|
||||
SizeOfXLogPHD + SizeOfXLogSubRecord != BLCKSZ)
|
||||
{
|
||||
elog(emode, "ReadRecord: invalid fragmented subrecord len %u in logfile %u seg %u off %u",
|
||||
@ -956,23 +967,26 @@ got_record:;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (BLCKSZ - SizeOfXLogRecord >=
|
||||
subrecord->xl_len + SizeOfXLogPHD + SizeOfXLogSubRecord)
|
||||
if (BLCKSZ - SizeOfXLogRecord >= DOUBLEALIGN(subrecord->xl_len) +
|
||||
SizeOfXLogPHD + SizeOfXLogSubRecord)
|
||||
{
|
||||
nextRecord = (XLogRecord *)
|
||||
((char *) subrecord + subrecord->xl_len + SizeOfXLogSubRecord);
|
||||
nextRecord = (XLogRecord *) ((char *) subrecord +
|
||||
DOUBLEALIGN(subrecord->xl_len) + SizeOfXLogSubRecord);
|
||||
}
|
||||
EndRecPtr.xlogid = readId;
|
||||
EndRecPtr.xrecoff = readSeg * XLogSegSize + readOff * BLCKSZ +
|
||||
SizeOfXLogPHD + SizeOfXLogSubRecord + subrecord->xl_len;
|
||||
SizeOfXLogPHD + SizeOfXLogSubRecord +
|
||||
DOUBLEALIGN(subrecord->xl_len);
|
||||
ReadRecPtr = *RecPtr;
|
||||
return (record);
|
||||
}
|
||||
if (BLCKSZ - SizeOfXLogRecord >=
|
||||
record->xl_len + RecPtr->xrecoff % BLCKSZ + SizeOfXLogRecord)
|
||||
nextRecord = (XLogRecord *) ((char *) record + record->xl_len + SizeOfXLogRecord);
|
||||
if (BLCKSZ - SizeOfXLogRecord >= DOUBLEALIGN(record->xl_len) +
|
||||
RecPtr->xrecoff % BLCKSZ + SizeOfXLogRecord)
|
||||
nextRecord = (XLogRecord *) ((char *) record +
|
||||
DOUBLEALIGN(record->xl_len) + SizeOfXLogRecord);
|
||||
EndRecPtr.xlogid = RecPtr->xlogid;
|
||||
EndRecPtr.xrecoff = RecPtr->xrecoff + record->xl_len + SizeOfXLogRecord;
|
||||
EndRecPtr.xrecoff = RecPtr->xrecoff +
|
||||
DOUBLEALIGN(record->xl_len) + SizeOfXLogRecord;
|
||||
ReadRecPtr = *RecPtr;
|
||||
|
||||
return (record);
|
||||
|
@ -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.29 2000/04/12 17:16:26 momjian Exp $
|
||||
* $Id: htup.h,v 1.30 2000/06/02 10:20:26 vadim Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -44,6 +44,8 @@ typedef struct HeapTupleHeaderData
|
||||
|
||||
uint8 t_hoff; /* sizeof tuple header */
|
||||
|
||||
/* ^ - 31 bytes - ^ */
|
||||
|
||||
bits8 t_bits[MinHeapTupleBitmapSize / 8];
|
||||
/* bit map of domains */
|
||||
|
||||
@ -52,6 +54,71 @@ typedef struct HeapTupleHeaderData
|
||||
|
||||
typedef HeapTupleHeaderData *HeapTupleHeader;
|
||||
|
||||
|
||||
#ifdef XLOG
|
||||
|
||||
/* XLOG stuff */
|
||||
|
||||
/*
|
||||
* XLOG allows to store some information in high 4 bits of log
|
||||
* record xl_info field
|
||||
*/
|
||||
#define XLOG_HEAP_INSERT 0x00
|
||||
#define XLOG_HEAP_DELETE 0x10
|
||||
#define XLOG_HEAP_UPDATE 0x20
|
||||
#define XLOG_HEAP_MOVE 0x30
|
||||
|
||||
/*
|
||||
* All what we need to find changed tuple (14 bytes)
|
||||
*/
|
||||
typedef struct xl_heaptid
|
||||
{
|
||||
Oid dbId; /* database */
|
||||
Oid relId; /* relation */
|
||||
ItemPointerData tid; /* changed tuple id */
|
||||
} xl_heaptid;
|
||||
|
||||
/* This is what we need to know about delete - ALIGN(14) = 16 bytes */
|
||||
typedef struct xl_heap_delete
|
||||
{
|
||||
xl_heaptid dtid; /* deleted tuple id */
|
||||
} xl_heap_delete;
|
||||
|
||||
/* This is what we need to know about insert - 22 + data */
|
||||
typedef struct xl_heap_insert
|
||||
{
|
||||
xl_heaptid itid; /* inserted tuple id */
|
||||
/* something from tuple header */
|
||||
int16 t_natts;
|
||||
Oid t_oid;
|
||||
uint8 t_hoff;
|
||||
uint8 mask; /* low 8 bits of t_infomask */
|
||||
/* TUPLE DATA FOLLOWS AT END OF STRUCT */
|
||||
} xl_heap_insert;
|
||||
|
||||
/* This is what we need to know about update - 28 + data */
|
||||
typedef struct xl_heap_update
|
||||
{
|
||||
xl_heaptid dtid; /* deleted tuple id */
|
||||
ItemPointerData itid; /* new inserted tuple id */
|
||||
/* something from header of new tuple version */
|
||||
int16 t_natts;
|
||||
uint8 t_hoff;
|
||||
uint8 mask; /* low 8 bits of t_infomask */
|
||||
/* NEW TUPLE DATA FOLLOWS AT END OF STRUCT */
|
||||
} xl_heap_update;
|
||||
|
||||
/* This is what we need to know about tuple move - ALIGN(20) = 24 bytes */
|
||||
typedef struct xl_heap_move
|
||||
{
|
||||
xl_heaptid ftid; /* moved from */
|
||||
ItemPointerData ttid; /* moved to */
|
||||
} xl_heap_move;
|
||||
|
||||
/* end of XLOG stuff */
|
||||
|
||||
#endif /* XLOG */
|
||||
|
||||
#define MinTupleSize (MAXALIGN(sizeof (PageHeaderData)) + \
|
||||
MAXALIGN(sizeof(HeapTupleHeaderData)) + \
|
||||
MAXALIGN(sizeof(char)))
|
||||
|
@ -47,7 +47,12 @@ typedef struct XLogSubRecord
|
||||
|
||||
#define SizeOfXLogSubRecord DOUBLEALIGN(sizeof(XLogSubRecord))
|
||||
|
||||
/*
|
||||
* XLOG uses only low 4 bits of xl_info. High 4 bits may be used
|
||||
* by rmgr...
|
||||
*/
|
||||
#define XLR_TO_BE_CONTINUED 0x01
|
||||
#define XLR_INFO_MASK 0x0F
|
||||
|
||||
#define XLOG_PAGE_MAGIC 0x17345168
|
||||
|
||||
@ -63,7 +68,8 @@ typedef XLogPageHeaderData *XLogPageHeader;
|
||||
|
||||
#define XLP_FIRST_IS_SUBRECORD 0x0001
|
||||
|
||||
extern XLogRecPtr XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen,
|
||||
extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info,
|
||||
char *hdr, uint32 hdrlen,
|
||||
char *buf, uint32 buflen);
|
||||
extern void XLogFlush(XLogRecPtr RecPtr);
|
||||
|
||||
|
@ -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.28 2000/01/26 05:58:32 momjian Exp $
|
||||
* $Id: bufpage.h,v 1.29 2000/06/02 10:20:27 vadim Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -117,6 +117,10 @@ typedef OpaqueData *Opaque;
|
||||
*/
|
||||
typedef struct PageHeaderData
|
||||
{
|
||||
#ifdef XLOG
|
||||
XLogRecPtr pd_lsn; /* XLOG: next byte after last byte of xlog */
|
||||
/* record for last change of this page */
|
||||
#endif
|
||||
LocationIndex pd_lower; /* offset to start of free space */
|
||||
LocationIndex pd_upper; /* offset to end of free space */
|
||||
LocationIndex pd_special; /* offset to start of special space */
|
||||
|
Loading…
Reference in New Issue
Block a user