From bf1c8f2b3b067c29f1abdf6fe866fb485ade96e9 Mon Sep 17 00:00:00 2001 From: "Vadim B. Mikheev" Date: Fri, 2 Jun 2000 10:20:27 +0000 Subject: [PATCH] heap' xlog records --- src/backend/access/heap/heapam.c | 37 ++++++++++++++++- src/backend/access/transam/xlog.c | 52 ++++++++++++++--------- src/include/access/htup.h | 69 ++++++++++++++++++++++++++++++- src/include/access/xlog.h | 10 ++++- src/include/storage/bufpage.h | 6 ++- 5 files changed, 150 insertions(+), 24 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 01553e422b..c99687e269 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -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(); diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 07a8392c4e..ca75cfefb1 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -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); diff --git a/src/include/access/htup.h b/src/include/access/htup.h index 784c5051a9..ff51409216 100644 --- a/src/include/access/htup.h +++ b/src/include/access/htup.h @@ -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))) diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index e2ab6e4f41..b5fda0b58a 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -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,8 +68,9 @@ typedef XLogPageHeaderData *XLogPageHeader; #define XLP_FIRST_IS_SUBRECORD 0x0001 -extern XLogRecPtr XLogInsert(RmgrId rmid, char *hdr, uint32 hdrlen, - char *buf, uint32 buflen); +extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info, + char *hdr, uint32 hdrlen, + char *buf, uint32 buflen); extern void XLogFlush(XLogRecPtr RecPtr); #endif /* XLOG_H */ diff --git a/src/include/storage/bufpage.h b/src/include/storage/bufpage.h index f1c2596395..15d1106f26 100644 --- a/src/include/storage/bufpage.h +++ b/src/include/storage/bufpage.h @@ -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 */ -- 2.40.0