On slow machines the modified test could end up switching the order in which
transactional stats are reported in one session and non-transactional stats in
another session. As stats handling of truncate is implemented as setting
live/dead rows 0, the order in which a truncate's stats changes are applied,
relative to normal stats updates, matters. The handling of stats for truncate
hasn't changed due to shared memory stats, this is longstanding behavior.
We might want to improve truncate's stats handling in the future, but for now
just change the order of forced flushed to make the test stable.
Reported-By: Christoph Berg <[email protected]>
Discussion: https://postgr.es/m/YoZf7U/
[email protected]
(1 row)
-starting permutation: s1_table_insert s1_begin s1_table_update_k1 s1_table_update_k1 s1_table_truncate s1_table_insert_k1 s1_table_update_k1 s1_prepare_a s2_commit_prepared_a s1_ff s2_ff s1_table_stats
+starting permutation: s1_table_insert s1_begin s1_table_update_k1 s1_table_update_k1 s1_table_truncate s1_table_insert_k1 s1_table_update_k1 s1_prepare_a s1_ff s2_commit_prepared_a s2_ff s1_table_stats
pg_stat_force_next_flush
------------------------
step s1_table_insert_k1: INSERT INTO test_stat_tab(key, value) VALUES('k1', 1);
step s1_table_update_k1: UPDATE test_stat_tab SET value = value + 1 WHERE key = 'k1';
step s1_prepare_a: PREPARE TRANSACTION 'a';
-step s2_commit_prepared_a: COMMIT PREPARED 'a';
step s1_ff: SELECT pg_stat_force_next_flush();
pg_stat_force_next_flush
------------------------
(1 row)
+step s2_commit_prepared_a: COMMIT PREPARED 'a';
step s2_ff: SELECT pg_stat_force_next_flush();
pg_stat_force_next_flush
------------------------
(1 row)
-starting permutation: s1_table_insert s1_begin s1_table_update_k1 s1_table_update_k1 s1_table_truncate s1_table_insert_k1 s1_table_update_k1 s1_prepare_a s2_commit_prepared_a s1_ff s2_ff s1_table_stats
+starting permutation: s1_table_insert s1_begin s1_table_update_k1 s1_table_update_k1 s1_table_truncate s1_table_insert_k1 s1_table_update_k1 s1_prepare_a s1_ff s2_commit_prepared_a s2_ff s1_table_stats
pg_stat_force_next_flush
------------------------
step s1_table_update_k1: UPDATE test_stat_tab SET value = value + 1 WHERE key = 'k1';
step s1_prepare_a: PREPARE TRANSACTION 'a';
ERROR: prepared transactions are disabled
-step s2_commit_prepared_a: COMMIT PREPARED 'a';
-ERROR: prepared transaction with identifier "a" does not exist
step s1_ff: SELECT pg_stat_force_next_flush();
pg_stat_force_next_flush
------------------------
(1 row)
+step s2_commit_prepared_a: COMMIT PREPARED 'a';
+ERROR: prepared transaction with identifier "a" does not exist
step s2_ff: SELECT pg_stat_force_next_flush();
pg_stat_force_next_flush
------------------------
s1_table_insert_k1 # should be counted
s1_table_update_k1 # dito
s1_prepare_a
+ s1_ff # flush out non-transactional stats, might happen anyway
s2_commit_prepared_a
- s1_ff s2_ff
+ s2_ff
s1_table_stats
# S1 prepares, S1 aborts prepared