Tweak md.c logic to cope with the situation where WAL replay tries to
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 30 Aug 2004 03:52:43 +0000 (03:52 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 30 Aug 2004 03:52:43 +0000 (03:52 +0000)
write into a high-numbered segment of a relation that was later deleted.
We need to temporarily recreate missing segment files, instead of
failing.

src/backend/storage/smgr/md.c

index 6e7ebed875e4c3f6aecfad2a99b6907350652fff..3bb4a05d07b70d4da39f5290277031ef0cccb6e8 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/storage/smgr/md.c,v 1.111 2004/08/30 02:54:39 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/storage/smgr/md.c,v 1.112 2004/08/30 03:52:43 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -937,10 +937,19 @@ _mdfd_getseg(SMgrRelation reln, BlockNumber blkno, bool allowNotFound)
             * "target" block.  We should never need to create more than
             * one new segment per call, so this restriction seems
             * reasonable.
+            *
+            * BUT: when doing WAL recovery, disable this logic and create
+            * segments unconditionally.  In this case it seems better
+            * to assume the given blkno is good (it presumably came from
+            * a CRC-checked WAL record); furthermore this lets us cope
+            * in the case where we are replaying WAL data that has a write
+            * into a high-numbered segment of a relation that was later
+            * deleted.  We want to go ahead and create the segments so
+            * we can finish out the replay.
             */
            v->mdfd_chain = _mdfd_openseg(reln,
                                          nextsegno,
-                                         (segstogo == 1) ? O_CREAT : 0);
+                                 (segstogo == 1 || InRecovery) ? O_CREAT : 0);
            if (v->mdfd_chain == NULL)
            {
                if (allowNotFound && errno == ENOENT)