]> granicus.if.org Git - postgresql/commitdiff
Write a WAL record whenever we perform an operation without WAL-logging
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 20 Jan 2010 19:43:40 +0000 (19:43 +0000)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 20 Jan 2010 19:43:40 +0000 (19:43 +0000)
that would've been WAL-logged if archiving was enabled. If we encounter
such records in archive recovery anyway, we know that some data is
missing from the log. A WARNING is emitted in that case.

Original patch by Fujii Masao, with changes by me.

src/backend/access/heap/heapam.c
src/backend/access/nbtree/nbtsort.c
src/backend/access/transam/xlog.c
src/backend/commands/cluster.c
src/backend/commands/tablecmds.c
src/include/access/xlog.h
src/include/catalog/pg_control.h

index 5cd4f005c6544a8a74208839d58c5cb779cf4a0d..ce661a8d1b37dd2620f0added470e600e422439d 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.282 2010/01/14 11:08:00 sriggs Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.283 2010/01/20 19:43:40 heikki Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -5074,10 +5074,16 @@ heap2_desc(StringInfo buf, uint8 xl_info, char *rec)
 void
 heap_sync(Relation rel)
 {
+       char reason[NAMEDATALEN + 30];
+
        /* temp tables never need fsync */
        if (rel->rd_istemp)
                return;
 
+       snprintf(reason, sizeof(reason), "heap inserts on \"%s\"",
+                        RelationGetRelationName(rel));
+       XLogReportUnloggedStatement(reason);
+
        /* main heap */
        FlushRelationBuffers(rel);
        /* FlushRelationBuffers will have opened rd_smgr */
index 68747beae5fdf4dc22c7f83ab3ae9cf8fc55c5b0..772215c1810f6913ddf028a7a4208650c7d0a8db 100644 (file)
@@ -59,7 +59,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsort.c,v 1.122 2010/01/15 09:19:00 heikki Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsort.c,v 1.123 2010/01/20 19:43:40 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -215,6 +215,18 @@ _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2)
         */
        wstate.btws_use_wal = XLogIsNeeded() && !wstate.index->rd_istemp;
 
+       /*
+        * Write an XLOG UNLOGGED record if WAL-logging was skipped because
+        * WAL archiving is not enabled.
+        */
+       if (!wstate.btws_use_wal && !wstate.index->rd_istemp)
+       {
+               char reason[NAMEDATALEN + 20];
+               snprintf(reason, sizeof(reason), "b-tree build on \"%s\"",
+                                RelationGetRelationName(wstate.index));
+               XLogReportUnloggedStatement(reason);
+       }
+
        /* reserve the metapage */
        wstate.btws_pages_alloced = BTREE_METAPAGE + 1;
        wstate.btws_pages_written = 0;
index a0dddcad8137aa584845d113661351e5c529dbf5..a7ff66a6b8614cd8ba5b5fdd069f8d3c39c4f5e7 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.358 2010/01/15 09:19:00 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.359 2010/01/20 19:43:40 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -7561,6 +7561,31 @@ RequestXLogSwitch(void)
        return RecPtr;
 }
 
+/*
+ * Write an XLOG UNLOGGED record, indicating that some operation was
+ * performed on data that we fsync()'d directly to disk, skipping
+ * WAL-logging.
+ *
+ * Such operations screw up archive recovery, so we complain if we see
+ * these records during archive recovery. That shouldn't happen in a
+ * correctly configured server, but you can induce it by temporarily
+ * disabling archiving and restarting, so it's good to at least get a
+ * warning of silent data loss in such cases. These records serve no
+ * other purpose and are simply ignored during crash recovery.
+ */
+void
+XLogReportUnloggedStatement(char *reason)
+{
+       XLogRecData rdata;
+
+       rdata.buffer = InvalidBuffer;
+       rdata.data = reason;
+       rdata.len = strlen(reason) + 1;
+       rdata.next = NULL;
+
+       XLogInsert(RM_XLOG_ID, XLOG_UNLOGGED, &rdata);
+}
+
 /*
  * XLOG resource manager's routines
  *
@@ -7703,6 +7728,19 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
                        LWLockRelease(ControlFileLock);
                }
        }
+       else if (info == XLOG_UNLOGGED)
+       {
+               if (InArchiveRecovery)
+               {
+                       /*
+                        * Note: We don't print the reason string from the record,
+                        * because that gets added as a line using xlog_desc()
+                        */
+                       ereport(WARNING,
+                                       (errmsg("unlogged operation performed, data may be missing"),
+                                        errhint("This can happen if you temporarily disable archive_mode without taking a new base backup.")));
+               }
+       }
 }
 
 void
@@ -7752,6 +7790,12 @@ xlog_desc(StringInfo buf, uint8 xl_info, char *rec)
                appendStringInfo(buf, "backup end: %X/%X",
                                                 startpoint.xlogid, startpoint.xrecoff);
        }
+       else if (info == XLOG_UNLOGGED)
+       {
+               char *reason = rec;
+
+               appendStringInfo(buf, "unlogged operation: %s", reason);
+       }
        else
                appendStringInfo(buf, "UNKNOWN");
 }
index 913ba1681c53d7ecb3dd448d170a59788cbd24d0..56d040590ba5d8ec3bfebc6d1d47b32c784d405a 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.193 2010/01/15 09:19:01 heikki Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.194 2010/01/20 19:43:40 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -821,6 +821,18 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex,
         */
        use_wal = XLogIsNeeded() && !NewHeap->rd_istemp;
 
+       /*
+        * Write an XLOG UNLOGGED record if WAL-logging was skipped because
+        * WAL archiving is not enabled.
+        */
+       if (!use_wal && !NewHeap->rd_istemp)
+       {
+               char reason[NAMEDATALEN + 20];
+               snprintf(reason, sizeof(reason), "CLUSTER on \"%s\"",
+                                RelationGetRelationName(NewHeap));
+               XLogReportUnloggedStatement(reason);
+       }
+
        /* use_wal off requires rd_targblock be initially invalid */
        Assert(NewHeap->rd_targblock == InvalidBlockNumber);
 
index 43d8c0c56bf3cd6252f94f53cc0896c4078b6036..0c5ccdcb45e85e829292b234662b0ff4464cfe9f 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.316 2010/01/17 22:56:21 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.317 2010/01/20 19:43:40 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -7015,6 +7015,19 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace)
 
        heap_close(pg_class, RowExclusiveLock);
 
+       /*
+        * Write an XLOG UNLOGGED record if WAL-logging was skipped because
+        * WAL archiving is not enabled.
+        */
+       if (!XLogIsNeeded() && !rel->rd_istemp)
+       {
+               char reason[NAMEDATALEN + 40];
+               snprintf(reason, sizeof(reason), "ALTER TABLE SET TABLESPACE on \"%s\"",
+                                RelationGetRelationName(rel));
+
+               XLogReportUnloggedStatement(reason);
+       }
+
        relation_close(rel, NoLock);
 
        /* Make sure the reltablespace change is visible */
@@ -7043,6 +7056,10 @@ copy_relation_data(SMgrRelation src, SMgrRelation dst,
        /*
         * We need to log the copied data in WAL iff WAL archiving/streaming is
         * enabled AND it's not a temp rel.
+        *
+        * Note: If you change the conditions here, update the conditions in
+        * ATExecSetTableSpace() for when an XLOG UNLOGGED record is written
+        * to match.
         */
        use_wal = XLogIsNeeded() && !istemp;
 
index d0cb6550b69821c4914af38472f8c0ed21ea0e6c..ca4d7f289a7c9bf12755c60fc741aa40130bd51f 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.97 2010/01/16 00:04:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.98 2010/01/20 19:43:40 heikki Exp $
  */
 #ifndef XLOG_H
 #define XLOG_H
@@ -278,6 +278,7 @@ extern void InitXLOGAccess(void);
 extern void CreateCheckPoint(int flags);
 extern bool CreateRestartPoint(int flags);
 extern void XLogPutNextOid(Oid nextOid);
+extern void XLogReportUnloggedStatement(char *reason);
 extern XLogRecPtr GetRedoRecPtr(void);
 extern XLogRecPtr GetInsertRecPtr(void);
 extern XLogRecPtr GetWriteRecPtr(void);
index bac3e2a7ee9157ad674262172445a223cd60b234..f064ef4acabf4c536f7371167090ada7274ce608 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.48 2010/01/04 12:50:50 heikki Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.49 2010/01/20 19:43:40 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -63,6 +63,7 @@ typedef struct CheckPoint
 #define XLOG_NEXTOID                                   0x30
 #define XLOG_SWITCH                                            0x40
 #define XLOG_BACKUP_END                                        0x50
+#define XLOG_UNLOGGED                                  0x60
 
 
 /* System status indicator */