]> granicus.if.org Git - postgresql/commitdiff
stats regression test's wait_for_stats() must check timestamp too.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 15 May 2017 03:33:03 +0000 (23:33 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 15 May 2017 03:33:18 +0000 (23:33 -0400)
pg_stat_get_snapshot_timestamp() returns the timestamp seen in the "global"
stats file.  Because pgstat_write_statsfiles() writes per-DB stats files
before the global file (or at least before renaming it into place), there
is a window where the test backend can see all the stats updates that
wait_for_stats() was checking for (all of which come from the per-DB file)
but also see the same global stats file it had seen at the start of the
test script.  This results in a failure in only the "snapshot_newer" query,
as reported by a couple of buildfarm members recently.

I suspect that this ought to be back-patched.  Commit 4e37b3e15 has
evidently increased the probability of this window getting hit, but
it's not apparent why it could not have been hit before.  I'll refrain
for the moment though.

src/test/regress/expected/stats.out
src/test/regress/sql/stats.sql

index c595442b93fbf8df8a5574c9806efc23f59562c4..fc91f3ce3652f9ce2a00201f0d5c43fa598486dd 100644 (file)
@@ -32,6 +32,7 @@ declare
   updated1 bool;
   updated2 bool;
   updated3 bool;
+  updated4 bool;
 begin
   -- we don't want to wait forever; loop will exit after 30 seconds
   for i in 1 .. 300 loop
@@ -55,7 +56,13 @@ begin
     SELECT (n_tup_ins > 0) INTO updated3
       FROM pg_stat_user_tables WHERE relname='trunc_stats_test4';
 
-    exit when updated1 and updated2 and updated3;
+    -- We must also check explicitly that pg_stat_get_snapshot_timestamp has
+    -- advanced, because that comes from the global stats file which might
+    -- be older than the per-DB stats file we got the other values from.
+    SELECT (pr.snap_ts < pg_stat_get_snapshot_timestamp()) INTO updated4
+      FROM prevstats AS pr;
+
+    exit when updated1 and updated2 and updated3 and updated4;
 
     -- wait a little
     perform pg_sleep_for('100 milliseconds');
index 026c93038f6534d9f77dbb94134c8666c4da9c34..6e882bf3acade32df1599c9be3f031be6dc9c8d2 100644 (file)
@@ -31,6 +31,7 @@ declare
   updated1 bool;
   updated2 bool;
   updated3 bool;
+  updated4 bool;
 begin
   -- we don't want to wait forever; loop will exit after 30 seconds
   for i in 1 .. 300 loop
@@ -54,7 +55,13 @@ begin
     SELECT (n_tup_ins > 0) INTO updated3
       FROM pg_stat_user_tables WHERE relname='trunc_stats_test4';
 
-    exit when updated1 and updated2 and updated3;
+    -- We must also check explicitly that pg_stat_get_snapshot_timestamp has
+    -- advanced, because that comes from the global stats file which might
+    -- be older than the per-DB stats file we got the other values from.
+    SELECT (pr.snap_ts < pg_stat_get_snapshot_timestamp()) INTO updated4
+      FROM prevstats AS pr;
+
+    exit when updated1 and updated2 and updated3 and updated4;
 
     -- wait a little
     perform pg_sleep_for('100 milliseconds');