Fix continuous agg isolation test

The test had a race condition between the Insert and Refresh. When the
invalidation log is released, if the Insert got it first it would write
a new invalidation that would be picked up by the refresh and if
Refresh got the lock first, it would not see any invalidations. Both
are valid paths for execution but caused non determinism in the tests.
This commit is contained in:
gayyappan 2019-06-26 13:35:57 -04:00 committed by gayyappan
parent d1f8f9d326
commit eddfa772b6
2 changed files with 39 additions and 28 deletions

View File

@ -1,4 +1,4 @@
Parsed test spec with 8 sessions
Parsed test spec with 12 sessions
starting permutation: LockCompleted Refresh2 Refresh UnlockCompleted
step LockCompleted: BEGIN; LOCK TABLE _timescaledb_catalog.continuous_aggs_completed_threshold;
@ -131,39 +131,35 @@ step Refresh: REFRESH MATERIALIZED VIEW continuous_view; <waiting ...>
step UnlockInval: ROLLBACK;
step Refresh: <... completed>
starting permutation: I1 Refresh LockInval Refresh Ib I1 Ic UnlockInval
step I1: INSERT INTO ts_continuous_test VALUES (1, 1);
starting permutation: Refresh SV1 LockMatInval Refresh1 Ib I1 LockInvalThrEx Ic UnlockMatInval UnlockInvalThrEx SV1
INFO: new materialization range for public.ts_continuous_test (time column time) (15)
INFO: materializing continuous aggregate public.continuous_view: new range up to 15
step Refresh: REFRESH MATERIALIZED VIEW continuous_view;
step LockInval: BEGIN; LOCK TABLE _timescaledb_catalog.continuous_aggs_hypertable_invalidation_log;
INFO: new materialization range not found for public.ts_continuous_test (time column time): not enough new data past completion threshold (15)
INFO: materializing continuous aggregate public.continuous_view: no new range to materialize
step Refresh: REFRESH MATERIALIZED VIEW continuous_view; <waiting ...>
step Ib: BEGIN; SET LOCAL lock_timeout = '50ms'; SET LOCAL deadlock_timeout = '10ms';
step I1: INSERT INTO ts_continuous_test VALUES (1, 1);
step Ic: COMMIT; <waiting ...>
step UnlockInval: ROLLBACK;
INFO: materializing continuous aggregate public.continuous_view: no new range to materialize or invalidations found, exiting early
step Refresh: <... completed>
step Ic: <... completed>
step SV1: SELECT * FROM continuous_view order by 1;
time_bucket count
starting permutation: I1 Refresh LockInval Ib I1 Refresh Ic UnlockInval
step I1: INSERT INTO ts_continuous_test VALUES (1, 1);
INFO: new materialization range for public.ts_continuous_test (time column time) (15)
INFO: materializing continuous aggregate public.continuous_view: new range up to 15
step Refresh: REFRESH MATERIALIZED VIEW continuous_view;
step LockInval: BEGIN; LOCK TABLE _timescaledb_catalog.continuous_aggs_hypertable_invalidation_log;
step Ib: BEGIN; SET LOCAL lock_timeout = '50ms'; SET LOCAL deadlock_timeout = '10ms';
step I1: INSERT INTO ts_continuous_test VALUES (1, 1);
0 5
5 5
10 5
step LockMatInval: BEGIN; LOCK TABLE _timescaledb_catalog.continuous_aggs_materialization_invalidation_log;
INFO: new materialization range not found for public.ts_continuous_test (time column time): not enough new data past completion threshold (15)
INFO: materializing continuous aggregate public.continuous_view: no new range to materialize
step Refresh: REFRESH MATERIALIZED VIEW continuous_view; <waiting ...>
step Refresh1: REFRESH MATERIALIZED VIEW continuous_view; <waiting ...>
step Ib: BEGIN; SET LOCAL lock_timeout = '50ms'; SET LOCAL deadlock_timeout = '10ms';
step I1: INSERT INTO ts_continuous_test VALUES (1, 1);
step LockInvalThrEx: BEGIN; LOCK TABLE _timescaledb_catalog.continuous_aggs_invalidation_threshold ;
step Ic: COMMIT; <waiting ...>
step UnlockInval: ROLLBACK;
step UnlockMatInval: ROLLBACK;
INFO: materializing continuous aggregate public.continuous_view: no new range to materialize or invalidations found, exiting early
step Refresh: <... completed>
step Refresh1: <... completed>
step UnlockInvalThrEx: ROLLBACK;
step Ic: <... completed>
step SV1: SELECT * FROM continuous_view order by 1;
time_bucket count
0 5
5 5
10 5
starting permutation: I1 Refresh LockInval Refresh Sb S1 Sc UnlockInval
step I1: INSERT INTO ts_continuous_test VALUES (1, 1);

View File

@ -32,9 +32,15 @@ step "Sb" { BEGIN; SET LOCAL lock_timeout = '50ms'; SET LOCAL deadlock_timeout =
step "S1" { SELECT count(*) FROM ts_continuous_test; }
step "Sc" { COMMIT; }
session "SV"
step "SV1" { SELECT * FROM continuous_view order by 1; }
session "R"
step "Refresh" { REFRESH MATERIALIZED VIEW continuous_view; }
session "R1"
step "Refresh1" { REFRESH MATERIALIZED VIEW continuous_view; }
session "R2"
setup { SET lock_timeout = '50ms'; SET deadlock_timeout = '10ms'; }
step "Refresh2" { REFRESH MATERIALIZED VIEW continuous_view; }
@ -46,16 +52,25 @@ step "LockInval" { BEGIN; LOCK TABLE _timescaledb_catalog.continuous_aggs_hypert
step "UnlockInval" { ROLLBACK; }
# the invalidation threshold lock will block both INSERT and REFRESH
session "L"
session "LI"
step "LockInvalThr" { BEGIN; LOCK TABLE _timescaledb_catalog.continuous_aggs_invalidation_threshold IN SHARE MODE; }
step "UnlockInvalThr" { ROLLBACK; }
# the invalidation threshold lock will block both INSERT and REFRESH
session "LIE"
step "LockInvalThrEx" { BEGIN; LOCK TABLE _timescaledb_catalog.continuous_aggs_invalidation_threshold ; }
step "UnlockInvalThrEx" { ROLLBACK; }
#the completed threshold will block the REFRESH in the second materialization
# txn , but not the INSERT
session "LC"
step "LockCompleted" { BEGIN; LOCK TABLE _timescaledb_catalog.continuous_aggs_completed_threshold; }
step "UnlockCompleted" { ROLLBACK; }
# the materialization invalidation log
session "LM"
step "LockMatInval" { BEGIN; LOCK TABLE _timescaledb_catalog.continuous_aggs_materialization_invalidation_log; }
step "UnlockMatInval" { ROLLBACK; }
#only one refresh
permutation "LockCompleted" "Refresh2" "Refresh" "UnlockCompleted"
@ -81,7 +96,7 @@ permutation "Ipb" "LockInval" "Ip1" "Ipc" "Refresh" "UnlockInval"
#refresh and insert/select do not block each other
permutation "I1" "Refresh" "LockInval" "Refresh" "Ib" "I1" "Ic" "UnlockInval"
permutation "I1" "Refresh" "LockInval" "Ib" "I1" "Refresh" "Ic" "UnlockInval"
#refresh1 is blocked on LockMatInval , insert is blocked on invalidation threshold. so refresh1 does not see the insert from I1
permutation "Refresh" "SV1" "LockMatInval" "Refresh1" "Ib" "I1" "LockInvalThrEx" "Ic" "UnlockMatInval" "UnlockInvalThrEx" "SV1"
permutation "I1" "Refresh" "LockInval" "Refresh" "Sb" "S1" "Sc" "UnlockInval"
permutation "I1" "Refresh" "LockInval" "Sb" "S1" "Refresh" "Sc" "UnlockInval"