pgstat: set timestamps of fixed-numbered stats after a crash.
authorAndres Freund
Fri, 15 Apr 2022 00:40:25 +0000 (17:40 -0700)
committerAndres Freund
Fri, 15 Apr 2022 00:40:25 +0000 (17:40 -0700)
When not loading stats at startup (i.e. pgstat_discard_stats() getting
called), reset timestamps of fixed numbered stats would be left at
0. Oversight in 5891c7a8ed8.

Instead use pgstat_reset_after_failure() and add tests verifying that
fixed-numbered reset timestamps are set appropriately.

Reported-By: "David G. Johnston"
Discussion: https://postgr.es/m/CAKFQuwamFuaQHKdhcMt4Gbw5+Hca2UE741B8gOOXoA=TtAd2Yw@mail.gmail.com

src/backend/utils/activity/pgstat.c
src/test/recovery/t/029_stats_restart.pl

index ea1cb8d1e3f3d7e4f53dfd61455e3b54c59ff46d..f658f8f19897e8165f8db1aac18507d7394069f9 100644 (file)
@@ -166,7 +166,7 @@ typedef struct PgStat_SnapshotEntry
 static void pgstat_write_statsfile(void);
 static void pgstat_read_statsfile(void);
 
-static void pgstat_reset_after_failure(TimestampTz ts);
+static void pgstat_reset_after_failure(void);
 
 static bool pgstat_flush_pending_entries(bool nowait);
 
@@ -427,6 +427,12 @@ pgstat_discard_stats(void)
                 errmsg("unlinked permanent statistics file \"%s\"",
                        PGSTAT_STAT_PERMANENT_FILENAME)));
    }
+
+   /*
+    * Reset stats contents. This will set reset timestamps of fixed-numbered
+    * stats to the current time (no variable stats exist).
+    */
+   pgstat_reset_after_failure();
 }
 
 /*
@@ -1422,7 +1428,6 @@ pgstat_read_statsfile(void)
    bool        found;
    const char *statfile = PGSTAT_STAT_PERMANENT_FILENAME;
    PgStat_ShmemControl *shmem = pgStatLocal.shmem;
-   TimestampTz ts = GetCurrentTimestamp();
 
    /* shouldn't be called from postmaster */
    Assert(IsUnderPostmaster || !IsPostmasterEnvironment);
@@ -1445,7 +1450,7 @@ pgstat_read_statsfile(void)
                    (errcode_for_file_access(),
                     errmsg("could not open statistics file \"%s\": %m",
                            statfile)));
-       pgstat_reset_after_failure(ts);
+       pgstat_reset_after_failure();
        return;
    }
 
@@ -1597,19 +1602,20 @@ error:
    ereport(LOG,
            (errmsg("corrupted statistics file \"%s\"", statfile)));
 
-   /* Set the current timestamp as reset timestamp */
-   pgstat_reset_after_failure(ts);
+   pgstat_reset_after_failure();
 
    goto done;
 }
 
 /*
- * Helper to reset / drop stats after restoring stats from disk failed,
- * potentially after already loading parts.
+ * Helper to reset / drop stats after a crash or after restoring stats from
+ * disk failed, potentially after already loading parts.
  */
 static void
-pgstat_reset_after_failure(TimestampTz ts)
+pgstat_reset_after_failure(void)
 {
+   TimestampTz ts = GetCurrentTimestamp();
+
    /* reset fixed-numbered stats */
    for (int kind = PGSTAT_KIND_FIRST_VALID; kind <= PGSTAT_KIND_LAST; kind++)
    {
index d3108127ef5f665d2e23cc76975b476c3b5b32bc..e0478f8af8d41e0bba71bc57fca0d0dd6c29df34 100644 (file)
@@ -250,6 +250,16 @@ cmp_ok(
    $wal_restart2->{reset},
    "$sect: newer stats_reset");
 
+$node->stop('immediate');
+$node->start;
+
+$sect = "post immediate restart";
+my $wal_restart_immediate = wal_stats();
+
+cmp_ok(
+   $wal_reset_restart->{reset}, 'lt',
+   $wal_restart_immediate->{reset},
+   "$sect: reset timestamp is new");
 
 $node->stop;
 done_testing();