Skip to content
Snippets Groups Projects
Commit bf1c8f2b authored by Vadim B. Mikheev's avatar Vadim B. Mikheev
Browse files

heap' xlog records

parent 664dd614
No related branches found
No related tags found
No related merge requests found
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
...@@ -1246,6 +1246,27 @@ heap_insert(Relation relation, HeapTuple tup) ...@@ -1246,6 +1246,27 @@ heap_insert(Relation relation, HeapTuple tup)
RelationPutHeapTupleAtEnd(relation, 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))) if (IsSystemRelationName(RelationGetRelationName(relation)))
RelationMark4RollbackHeapTuple(relation, tup); RelationMark4RollbackHeapTuple(relation, tup);
...@@ -1333,6 +1354,20 @@ l1: ...@@ -1333,6 +1354,20 @@ l1:
return result; 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 */ /* store transaction information of xact deleting the tuple */
TransactionIdStore(GetCurrentTransactionId(), &(tp.t_data->t_xmax)); TransactionIdStore(GetCurrentTransactionId(), &(tp.t_data->t_xmax));
tp.t_data->t_cmax = GetCurrentCommandId(); tp.t_data->t_cmax = GetCurrentCommandId();
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,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
* *
* $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]; ...@@ -219,7 +219,7 @@ static char readBuf[BLCKSZ];
static XLogRecord *nextRecord = NULL; static XLogRecord *nextRecord = NULL;
XLogRecPtr 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; XLogCtlInsert *Insert = &XLogCtl->Insert;
XLogRecord *record; XLogRecord *record;
...@@ -231,6 +231,7 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen) ...@@ -231,6 +231,7 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen)
uint16 curridx; uint16 curridx;
bool updrqst = false; bool updrqst = false;
Assert(!(info & XLR_INFO_MASK));
if (len == 0 || len > MAXLOGRECSZ) if (len == 0 || len > MAXLOGRECSZ)
elog(STOP, "XLogInsert: invalid record len %u", len); elog(STOP, "XLogInsert: invalid record len %u", len);
...@@ -306,7 +307,8 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen) ...@@ -306,7 +307,8 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen)
} }
record->xl_xid = GetCurrentTransactionId(); record->xl_xid = GetCurrentTransactionId();
record->xl_len = (len > freespace) ? freespace : len; 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; record->xl_rmid = rmid;
RecPtr.xlogid = XLogCtl->xlblocks[curridx].xlogid; RecPtr.xlogid = XLogCtl->xlblocks[curridx].xlogid;
RecPtr.xrecoff = RecPtr.xrecoff =
...@@ -318,8 +320,7 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen) ...@@ -318,8 +320,7 @@ XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, char *buf, uint32 buflen)
MyProc->logRec = RecPtr; MyProc->logRec = RecPtr;
SpinRelease(SInvalLock); SpinRelease(SInvalLock);
} }
MyLastRecPtr = RecPtr; MyLastRecPtr = RecPtr; /* begin of record */
RecPtr.xrecoff += record->xl_len;
Insert->currpos += SizeOfXLogRecord; Insert->currpos += SizeOfXLogRecord;
if (freespace > 0) if (freespace > 0)
{ {
...@@ -364,6 +365,7 @@ nbuf: ...@@ -364,6 +365,7 @@ nbuf:
if (hdrlen > freespace) if (hdrlen > freespace)
{ {
subrecord->xl_len = freespace; subrecord->xl_len = freespace;
/* we don't store info in subrecord' xl_info */
subrecord->xl_info = XLR_TO_BE_CONTINUED; subrecord->xl_info = XLR_TO_BE_CONTINUED;
memcpy(Insert->currpos, hdr, freespace); memcpy(Insert->currpos, hdr, freespace);
hdrlen -= freespace; hdrlen -= freespace;
...@@ -383,6 +385,7 @@ nbuf: ...@@ -383,6 +385,7 @@ nbuf:
if (buflen > freespace) if (buflen > freespace)
{ {
subrecord->xl_len += freespace; subrecord->xl_len += freespace;
/* we don't store info in subrecord' xl_info */
subrecord->xl_info = XLR_TO_BE_CONTINUED; subrecord->xl_info = XLR_TO_BE_CONTINUED;
memcpy(Insert->currpos, buf, freespace); memcpy(Insert->currpos, buf, freespace);
buflen -= freespace; buflen -= freespace;
...@@ -395,15 +398,22 @@ nbuf: ...@@ -395,15 +398,22 @@ nbuf:
memcpy(Insert->currpos, buf, buflen); memcpy(Insert->currpos, buf, buflen);
Insert->currpos += buflen; Insert->currpos += buflen;
} }
/* we don't store info in subrecord' xl_info */
subrecord->xl_info = 0; 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) + Insert->currpos = ((char *) Insert->currpage) +
DOUBLEALIGN(Insert->currpos - ((char *) Insert->currpage)); DOUBLEALIGN(Insert->currpos - ((char *) Insert->currpage));
} }
freespace = ((char *) Insert->currpage) + BLCKSZ - Insert->currpos; 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. * All done! Update global LgwrRqst if some block was filled up.
*/ */
...@@ -884,7 +894,8 @@ got_record:; ...@@ -884,7 +894,8 @@ got_record:;
XLogSubRecord *subrecord; XLogSubRecord *subrecord;
uint32 len = record->xl_len; 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)", elog(emode, "ReadRecord: invalid fragmented record len %u in (%u, %u)",
record->xl_len, RecPtr->xlogid, RecPtr->xrecoff); record->xl_len, RecPtr->xlogid, RecPtr->xrecoff);
...@@ -945,7 +956,7 @@ got_record:; ...@@ -945,7 +956,7 @@ got_record:;
buffer += subrecord->xl_len; buffer += subrecord->xl_len;
if (subrecord->xl_info & XLR_TO_BE_CONTINUED) if (subrecord->xl_info & XLR_TO_BE_CONTINUED)
{ {
if (subrecord->xl_len + if (DOUBLEALIGN(subrecord->xl_len) +
SizeOfXLogPHD + SizeOfXLogSubRecord != BLCKSZ) SizeOfXLogPHD + SizeOfXLogSubRecord != BLCKSZ)
{ {
elog(emode, "ReadRecord: invalid fragmented subrecord len %u in logfile %u seg %u off %u", elog(emode, "ReadRecord: invalid fragmented subrecord len %u in logfile %u seg %u off %u",
...@@ -956,23 +967,26 @@ got_record:; ...@@ -956,23 +967,26 @@ got_record:;
} }
break; break;
} }
if (BLCKSZ - SizeOfXLogRecord >= if (BLCKSZ - SizeOfXLogRecord >= DOUBLEALIGN(subrecord->xl_len) +
subrecord->xl_len + SizeOfXLogPHD + SizeOfXLogSubRecord) SizeOfXLogPHD + SizeOfXLogSubRecord)
{ {
nextRecord = (XLogRecord *) nextRecord = (XLogRecord *) ((char *) subrecord +
((char *) subrecord + subrecord->xl_len + SizeOfXLogSubRecord); DOUBLEALIGN(subrecord->xl_len) + SizeOfXLogSubRecord);
} }
EndRecPtr.xlogid = readId; EndRecPtr.xlogid = readId;
EndRecPtr.xrecoff = readSeg * XLogSegSize + readOff * BLCKSZ + EndRecPtr.xrecoff = readSeg * XLogSegSize + readOff * BLCKSZ +
SizeOfXLogPHD + SizeOfXLogSubRecord + subrecord->xl_len; SizeOfXLogPHD + SizeOfXLogSubRecord +
DOUBLEALIGN(subrecord->xl_len);
ReadRecPtr = *RecPtr; ReadRecPtr = *RecPtr;
return (record); return (record);
} }
if (BLCKSZ - SizeOfXLogRecord >= if (BLCKSZ - SizeOfXLogRecord >= DOUBLEALIGN(record->xl_len) +
record->xl_len + RecPtr->xrecoff % BLCKSZ + SizeOfXLogRecord) RecPtr->xrecoff % BLCKSZ + SizeOfXLogRecord)
nextRecord = (XLogRecord *) ((char *) record + record->xl_len + SizeOfXLogRecord); nextRecord = (XLogRecord *) ((char *) record +
DOUBLEALIGN(record->xl_len) + SizeOfXLogRecord);
EndRecPtr.xlogid = RecPtr->xlogid; EndRecPtr.xlogid = RecPtr->xlogid;
EndRecPtr.xrecoff = RecPtr->xrecoff + record->xl_len + SizeOfXLogRecord; EndRecPtr.xrecoff = RecPtr->xrecoff +
DOUBLEALIGN(record->xl_len) + SizeOfXLogRecord;
ReadRecPtr = *RecPtr; ReadRecPtr = *RecPtr;
return (record); return (record);
......
...@@ -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.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 ...@@ -44,6 +44,8 @@ typedef struct HeapTupleHeaderData
uint8 t_hoff; /* sizeof tuple header */ uint8 t_hoff; /* sizeof tuple header */
/* ^ - 31 bytes - ^ */
bits8 t_bits[MinHeapTupleBitmapSize / 8]; bits8 t_bits[MinHeapTupleBitmapSize / 8];
/* bit map of domains */ /* bit map of domains */
...@@ -52,6 +54,71 @@ typedef struct HeapTupleHeaderData ...@@ -52,6 +54,71 @@ typedef struct HeapTupleHeaderData
typedef HeapTupleHeaderData *HeapTupleHeader; 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)) + \ #define MinTupleSize (MAXALIGN(sizeof (PageHeaderData)) + \
MAXALIGN(sizeof(HeapTupleHeaderData)) + \ MAXALIGN(sizeof(HeapTupleHeaderData)) + \
MAXALIGN(sizeof(char))) MAXALIGN(sizeof(char)))
......
...@@ -47,7 +47,12 @@ typedef struct XLogSubRecord ...@@ -47,7 +47,12 @@ typedef struct 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
* by rmgr...
*/
#define XLR_TO_BE_CONTINUED 0x01 #define XLR_TO_BE_CONTINUED 0x01
#define XLR_INFO_MASK 0x0F
#define XLOG_PAGE_MAGIC 0x17345168 #define XLOG_PAGE_MAGIC 0x17345168
...@@ -63,7 +68,8 @@ typedef XLogPageHeaderData *XLogPageHeader; ...@@ -63,7 +68,8 @@ typedef XLogPageHeaderData *XLogPageHeader;
#define XLP_FIRST_IS_SUBRECORD 0x0001 #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); char *buf, uint32 buflen);
extern void XLogFlush(XLogRecPtr RecPtr); extern void XLogFlush(XLogRecPtr RecPtr);
......
...@@ -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: 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; ...@@ -117,6 +117,10 @@ typedef OpaqueData *Opaque;
*/ */
typedef struct PageHeaderData 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_lower; /* offset to start of free space */
LocationIndex pd_upper; /* offset to end of free space */ LocationIndex pd_upper; /* offset to end of free space */
LocationIndex pd_special; /* offset to start of special space */ LocationIndex pd_special; /* offset to start of special space */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment