pgstat: set timestamps of fixed-numbered stats after a crash.
authorAndres Freund <[email protected]>
Fri, 15 Apr 2022 00:40:25 +0000 (17:40 -0700)
committerAndres Freund <[email protected]>
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" <[email protected]>
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();