]> granicus.if.org Git - postgresql/commitdiff
heap' xlog records
authorVadim B. Mikheev <vadim4o@yahoo.com>
Fri, 2 Jun 2000 10:20:27 +0000 (10:20 +0000)
committerVadim B. Mikheev <vadim4o@yahoo.com>
Fri, 2 Jun 2000 10:20:27 +0000 (10:20 +0000)
src/backend/access/heap/heapam.c
src/backend/access/transam/xlog.c
src/include/access/htup.h
src/include/access/xlog.h
src/include/storage/bufpage.h

index 01553e422b093dd663151db04b10bda3204a0dd1..c99687e26995bdad850397e6b6ee419e0b41ed37 100644 (file)
@@ -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();
index 07a8392c4e443905cc6f36378bf9ae89d9236d05..ca75cfefb1815981764ba6a0a4ee107c3b2d1e38 100644 (file)
@@ -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);
index 784c5051a93c5083f0f73edd16bfcc9af283ca56..ff51409216043bd3ca9405d5cea6ceb533130ac3 100644 (file)
@@ -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)))
index e2ab6e4f417bb9d7390236b218189af230584241..b5fda0b58ad4c6dc448edccdd373a917c8049408 100644 (file)
@@ -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 */
index f1c25963951832525456d9dcfeb85b6c917fd887..15d1106f26c11271cb4c84882764be8bba7d12f8 100644 (file)
@@ -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 */