Commit 43e08419 authored by Andres Freund's avatar Andres Freund

Test additional speculative conflict scenarios.

Previously, the speculative insert tests did not cover the case when a
tuple t is inserted into a table with a unique index on a column but
before it can insert into the index, a concurrent transaction has
inserted a conflicting value into the index and the insertion of tuple t
must be aborted.

The basic permutation is one session successfully inserts into the table
and an associated unique index while a concurrent session successfully
inserts into the table but discovers a conflict before inserting into
the index and must abort the insertion.

Several variants on this include:
- swap which session is successful
- first session insert transaction does not commit, so second session
must wait on a transaction lock
- first session insert does not "complete", so second session must wait
on a speculative insertion lock

Also, refactor the existing TOAST table upsert test to be in the same
spec and reuse the steps.

Author: Melanie Plageman, Ashwin Agrawal, Andres Freund
Reviewed-by: Andres Freund, Taylor Vesely
Discussion: https://postgr.es/m/CAAKRu_ZRmxy_OEryfY3G8Zp01ouhgw59_-_Cm8n7LzRH5BAvng@mail.gmail.com
parent be6221e9
Parsed test spec with 3 sessions
starting permutation: s2insert s3insert s1commit
pg_advisory_xact_lock
step s2insert:
INSERT INTO ctoast (key, val) VALUES (1, ctoast_large_val()) ON CONFLICT DO NOTHING;
<waiting ...>
step s3insert:
INSERT INTO ctoast (key, val) VALUES (1, ctoast_large_val()) ON CONFLICT DO NOTHING;
<waiting ...>
step s1commit: COMMIT;
step s2insert: <... completed>
step s3insert: <... completed>
......@@ -38,7 +38,6 @@ test: insert-conflict-do-nothing-2
test: insert-conflict-do-update
test: insert-conflict-do-update-2
test: insert-conflict-do-update-3
test: insert-conflict-toast
test: insert-conflict-specconflict
test: delete-abort-savept
test: delete-abort-savept-2
......
# INSERT...ON CONFLICT test on table with TOAST
#
# This test verifies that speculatively inserted toast rows do not
# cause conflicts. It does so by using expression index over a
# function which acquires an advisory lock, triggering two index
# insertions to happen almost at the same time. This is not guaranteed
# to lead to a failed speculative insertion, but makes one quite
# likely.
setup
{
CREATE TABLE ctoast (key int primary key, val text);
CREATE OR REPLACE FUNCTION ctoast_lock_func(int) RETURNS INT IMMUTABLE LANGUAGE SQL AS 'select pg_advisory_xact_lock_shared(1); select $1;';
CREATE OR REPLACE FUNCTION ctoast_large_val() RETURNS TEXT LANGUAGE SQL AS 'select array_agg(md5(g::text))::text from generate_series(1, 256) g';
CREATE UNIQUE INDEX ctoast_lock_idx ON ctoast (ctoast_lock_func(key));
}
teardown
{
DROP TABLE ctoast;
DROP FUNCTION ctoast_lock_func(int);
DROP FUNCTION ctoast_large_val();
}
session "s1"
setup
{
BEGIN ISOLATION LEVEL READ COMMITTED;
SELECT pg_advisory_xact_lock(1);
}
step "s1commit" { COMMIT; }
session "s2"
setup
{
SET default_transaction_isolation = 'read committed';
}
step "s2insert" {
INSERT INTO ctoast (key, val) VALUES (1, ctoast_large_val()) ON CONFLICT DO NOTHING;
}
session "s3"
setup
{
SET default_transaction_isolation = 'read committed';
}
step "s3insert" {
INSERT INTO ctoast (key, val) VALUES (1, ctoast_large_val()) ON CONFLICT DO NOTHING;
}
permutation "s2insert" "s3insert" "s1commit"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment