*
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.156 2007/04/11 20:47:37 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.157 2007/05/20 21:08:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
         * Log the new item and its offset, if it was inserted on the left
         * page. (If it was put on the right page, we don't need to explicitly
         * WAL log it because it's included with all the other items on the
-        * right page.) Show these as belonging to the left page buffer,
-        * so that they are not stored if XLogInsert decides it needs a
-        * full-page image of the left page.
+        * right page.) Show the new item as belonging to the left page buffer,
+        * so that it is not stored if XLogInsert decides it needs a full-page
+        * image of the left page.  We store the offset anyway, though, to
+        * support archive compression of these records.
         */
        if (newitemonleft)
        {
            lastrdata->next = lastrdata + 1;
            lastrdata++;
+
            lastrdata->data = (char *) &newitemoff;
            lastrdata->len = sizeof(OffsetNumber);
-           lastrdata->buffer = buf;        /* backup block 1 */
-           lastrdata->buffer_std = true;
+           lastrdata->buffer = InvalidBuffer;
 
            lastrdata->next = lastrdata + 1;
            lastrdata++;
+
            lastrdata->data = (char *) newitem;
            lastrdata->len = MAXALIGN(newitemsz);
            lastrdata->buffer = buf;        /* backup block 1 */
             */
            lastrdata->next = lastrdata + 1;
            lastrdata++;
+
            lastrdata->data = NULL;
            lastrdata->len = 0;
            lastrdata->buffer = buf;        /* backup block 1 */
 
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.43 2007/04/11 20:47:38 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.44 2007/05/20 21:08:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
    }
 
    /* Extract newitem and newitemoff, if present */
-   if (onleft && !(record->xl_info & XLR_BKP_BLOCK_1))
+   if (onleft)
    {
-       IndexTupleData itupdata;
-
        /* Extract the offset (still assuming 16-bit alignment) */
        memcpy(&newitemoff, datapos, sizeof(OffsetNumber));
        datapos += sizeof(OffsetNumber);
        datalen -= sizeof(OffsetNumber);
+   }
+
+   if (onleft && !(record->xl_info & XLR_BKP_BLOCK_1))
+   {
+       IndexTupleData itupdata;
 
        /*
         * We need to copy the tuple header to apply IndexTupleDSize, because
 
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.268 2007/04/30 21:01:52 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.269 2007/05/20 21:08:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
        }
    }
 
+   /*
+    * If we backed up any full blocks and online backup is not in progress,
+    * mark the backup blocks as removable.  This allows the WAL archiver to
+    * know whether it is safe to compress archived WAL data by transforming
+    * full-block records into the non-full-block format.
+    *
+    * Note: we could just set the flag whenever !forcePageWrites, but
+    * defining it like this leaves the info bit free for some potential
+    * other use in records without any backup blocks.
+    */
+   if ((info & XLR_BKP_BLOCK_MASK) && !Insert->forcePageWrites)
+       info |= XLR_BKP_REMOVABLE;
+
    /*
     * If there isn't enough space on the current XLOG page for a record
     * header, advance to the next page (leaving the unused space as zeroes).
 
        RecoveryRestartPoint(&checkPoint);
    }
+   else if (info == XLOG_NOOP)
+   {
+       /* nothing to do here */
+   }
    else if (info == XLOG_SWITCH)
    {
        /* nothing to do here */
                         checkpoint->nextMultiOffset,
                 (info == XLOG_CHECKPOINT_SHUTDOWN) ? "shutdown" : "online");
    }
+   else if (info == XLOG_NOOP)
+   {
+       appendStringInfo(buf, "xlog no-op");
+   }
    else if (info == XLOG_NEXTOID)
    {
        Oid         nextOid;
 
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.76 2007/01/05 22:19:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.77 2007/05/20 21:08:19 tgl Exp $
  */
 #ifndef XLOG_H
 #define XLOG_H
 /*
  * If we backed up any disk blocks with the XLOG record, we use flag bits in
  * xl_info to signal it.  We support backup of up to 3 disk blocks per XLOG
- * record. (Could support 4 if we cared to dedicate all the xl_info bits for
- * this purpose; currently bit 0 of xl_info is unused and available.)
+ * record.
  */
 #define XLR_BKP_BLOCK_MASK     0x0E    /* all info bits used for bkp blocks */
 #define XLR_MAX_BKP_BLOCKS     3
 #define XLR_BKP_BLOCK_2            XLR_SET_BKP_BLOCK(1)    /* 0x04 */
 #define XLR_BKP_BLOCK_3            XLR_SET_BKP_BLOCK(2)    /* 0x02 */
 
+/*
+ * Bit 0 of xl_info is set if the backed-up blocks could safely be removed
+ * from a compressed version of XLOG (that is, they are backed up only to
+ * prevent partial-page-write problems, and not to ensure consistency of PITR
+ * recovery).  The compression algorithm would need to extract data from the
+ * blocks to create an equivalent non-full-page XLOG record.
+ */
+#define XLR_BKP_REMOVABLE      0x01
+
 /*
  * Sometimes we log records which are out of transaction control.
  * Rmgr may "or" XLOG_NO_TRAN into info passed to XLogInsert to indicate this.
 
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/xlog_internal.h,v 1.20 2007/04/30 21:01:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/xlog_internal.h,v 1.21 2007/05/20 21:08:19 tgl Exp $
  */
 #ifndef XLOG_INTERNAL_H
 #define XLOG_INTERNAL_H
 /*
  * Each page of XLOG file has a header like this:
  */
-#define XLOG_PAGE_MAGIC 0xD061 /* can be used as WAL version indicator */
+#define XLOG_PAGE_MAGIC 0xD062 /* can be used as WAL version indicator */
 
 typedef struct XLogPageHeaderData
 {
 
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.37 2007/04/03 04:14:26 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.38 2007/05/20 21:08:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 /* XLOG info values for XLOG rmgr */
 #define XLOG_CHECKPOINT_SHUTDOWN       0x00
 #define XLOG_CHECKPOINT_ONLINE         0x10
+#define XLOG_NOOP                      0x20
 #define XLOG_NEXTOID                   0x30
 #define XLOG_SWITCH                        0x40