pg_rewind: Fix thinko in parsing target WAL.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 10 Nov 2020 17:25:46 +0000 (19:25 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 10 Nov 2020 17:25:46 +0000 (19:25 +0200)
It's entirely possible to see WAL for a relation that doesn't exist in
the target anymore. That happens when the relation was dropped later.
The refactoring in commit eb00f1d4b broke that case, by sanity-checking
the file type in the target before checking the flag forwhether it
exists there at all.

I noticed this during manual testing. Modify the 001_basic.pl test so
that it covers this case.

src/bin/pg_rewind/filemap.c
src/bin/pg_rewind/t/001_basic.pl

index 314b064b22333cb8ff9e3d84da7d3d8780eec56f..ba34dbac1468f548e6d981f83d58a9cddce4be6e 100644 (file)
@@ -324,17 +324,20 @@ process_target_wal_block_change(ForkNumber forknum, RelFileNode rnode,
        {
                Assert(entry->isrelfile);
 
-               if (entry->target_type != FILE_TYPE_REGULAR)
-                       pg_fatal("unexpected page modification for non-regular file \"%s\"",
-                                        entry->path);
-
-               if (entry->target_exists && entry->source_exists)
+               if (entry->target_exists)
                {
-                       off_t           end_offset;
+                       if (entry->target_type != FILE_TYPE_REGULAR)
+                               pg_fatal("unexpected page modification for non-regular file \"%s\"",
+                                                entry->path);
 
-                       end_offset = (blkno_inseg + 1) * BLCKSZ;
-                       if (end_offset <= entry->source_size && end_offset <= entry->target_size)
-                               datapagemap_add(&entry->target_pages_to_overwrite, blkno_inseg);
+                       if (entry->source_exists)
+                       {
+                               off_t           end_offset;
+
+                               end_offset = (blkno_inseg + 1) * BLCKSZ;
+                               if (end_offset <= entry->source_size && end_offset <= entry->target_size)
+                                       datapagemap_add(&entry->target_pages_to_overwrite, blkno_inseg);
+                       }
                }
        }
 }
index ba528e262f32d8219bf353b786dff67faabfa048..93fa09467b41dcfd3343285d21ea52569f2bc6d5 100644 (file)
@@ -71,6 +71,7 @@ sub run_test
        primary_psql("VACUUM tail_tbl");
 
        # Drop drop_tbl. pg_rewind should copy it back.
+       primary_psql("insert into drop_tbl values ('in primary, after promotion')");
        primary_psql("DROP TABLE drop_tbl");
 
        # Before running pg_rewind, do a couple of extra tests with several