Hi, On 2019-05-15 20:35:49 -0700, Melanie Plageman wrote: > > > I noticed that there is not a test case which would cover the speculative > > > wait > > > codepath. This seems much more challenging, however, it does seem like a > > > worthwhile test to have. > > > > Shouldn't be that hard to create, I think. I think acquiring another > > lock in a second, non-unique, expression index, ought to do the trick? > > It probably has to be created after the unique index (so it's later in > > the > > > > > I would think that the sequence would be s1 and s2 probe the index, s1 and > s2 > insert into the table, s1 updates the index but does not complete the > speculative insert and clear the token (pause before > table_complete_speculative). s2 is in speculative wait when attempting to > update > the index. > > Something like > > permutation > "controller_locks" > "controller_show" > "s1_upsert" "s2_upsert" > "controller_show" > "controller_unlock_1_1" "controller_unlock_2_1" > "controller_unlock_1_3" "controller_unlock_2_3" > "controller_unlock_1_2" > "s1_magically_pause_before_complete_speculative" > # put s2 in speculative wait > "controller_unlock_2_2" > "s1_magically_unpause_before_complete_speculative" > > So, how would another lock on another index keep s1 from clearing the > speculative token after it has updated the index?
If there were a second index on upserttest, something like CREATE INDEX ON upserttest((blurt_and_lock2(key))); and blurt_and_lock2 acquired a lock on (current_setting('spec.session')::int, 4), ISTM you could cause a block to happen after the first index (the unique one, used for ON CONFLICT) successfully created the index entry, but before complete_speculative is called. Shouldn't that fulfil your s1_magically_pause_before_complete_speculative goal? The controller_locks would only acquire the (1, 4) lock, thereby *not* blocking s2 (or you could just release the lock in a separate step). Greetings, Andres Freund