diff --git a/product_docs/docs/bdr/3.7/isolation_details.mdx b/product_docs/docs/bdr/3.7/isolation_details.mdx index ae853d99c18..39a2eaea788 100644 --- a/product_docs/docs/bdr/3.7/isolation_details.mdx +++ b/product_docs/docs/bdr/3.7/isolation_details.mdx @@ -4,3861 +4,4 @@ originalFilePath: isolation/details.md --- -This section documents in detail the behavior of BDR4 when -**conflicts** occur. - -For every isolation test, the *expected output* is displayed, with -additional annotations commenting the context and the interpretation -of the outcomes. - -Each test is defined by a sequence of specific DML actions; the -following table provides links to each relevant combination: - -| | `INSERT` | `UPDATE` | `DELETE` | `TRUNCATE` | -| ------------------: | :------: | :------: | :------: | :--------: | -| `INSERT` | [ii][] | [iu][] | [id][] | [it][] | -| `UPDATE` | [iu][] | [uu][] | [ud][] | [ut][] | -| `DELETE` | [id][] | [ud][] | [dd][] | [dt][] | -| `TRUNCATE` | [it][] | [ut][] | [dt][] | [tt][] | -| `INSERT-INSERT` | [iii][] | [iiu][] | [iid][] | [iit][] | -| `UPDATE-UPDATE` | - | [uuu][] | [uud][] | [uut][] | -| `UPDATE-DELETE` | - | - | - | [udt][] | -| `DELETE-UPDATE` | - | [duu][] | - | - | -| `DELETE-DELETE` | - | - | [ddd][] | [ddt][] | -| `TRUNCATE-UPDATE` | - | [tuu][] | - | - | -| `TRUNCATE-TRUNCATE` | - | - | - | [ttt][] | - -[ii]: #test-two_node_dmlconflict_ii - -[iu]: #test-two_node_dmlconflict_iu - -[id]: #test-two_node_dmlconflict_id - -[it]: #test-two_node_dmlconflict_it - -[uu]: #test-two_node_dmlconflict_uu - -[ud]: #test-two_node_dmlconflict_ud - -[ut]: #test-two_node_dmlconflict_ut - -[dd]: #test-two_node_dmlconflict_dd - -[dt]: #test-two_node_dmlconflict_dt - -[tt]: #test-two_node_dmlconflict_tt - -[iii]: #test-three_node_dmlconflict_iii - -[iiu]: #test-three_node_dmlconflict_iiu - -[iid]: #test-three_node_dmlconflict_iid - -[iit]: #test-three_node_dmlconflict_iit - -[uuu]: #test-three_node_dmlconflict_uuu - -[uud]: #test-three_node_dmlconflict_uud - -[uut]: #test-three_node_dmlconflict_uut - -[udt]: #test-three_node_dmlconflict_udt - -[duu]: #test-three_node_dmlconflict_duu - -[ddd]: #test-three_node_dmlconflict_ddd - -[ddt]: #test-three_node_dmlconflict_ddt - -[tuu]: #test-three_node_dmlconflict_tuu - -[ttt]: #test-three_node_dmlconflict_ttt - -## Test `two_node_dmlconflict_ii` - -``` -Parsed test spec with 2 sessions - -starting permutation: s1i s2i s1w s2w s1s s2s -``` - -We insert a row into `node1`: - -``` -step s1i: INSERT INTO test_dmlconflict VALUES('x', 1, 'foo'); -``` - -We insert a row with the same primary key into `node2`: - -``` -step s2i: INSERT INTO test_dmlconflict VALUES('y', 1, 'bar'); -``` - -We wait until `INSERT` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until `INSERT` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar - -starting permutation: s1a s2a s1i s2i s1w s2w s1s s2s s1teardown s2teardown -step s1a: SELECT bdr.alter_node_set_conflict_resolver('node1', 'insert_exists', 'skip'); -alter_node_set_conflict_resolver - -t -step s2a: SELECT bdr.alter_node_set_conflict_resolver('node2', 'insert_exists', 'skip'); -alter_node_set_conflict_resolver - -t -``` - -We insert a row into `node1`: - -``` -step s1i: INSERT INTO test_dmlconflict VALUES('x', 1, 'foo'); -``` - -We insert a row with the same primary key into `node2`: - -``` -step s2i: INSERT INTO test_dmlconflict VALUES('y', 1, 'bar'); -``` - -We wait until `INSERT` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until `INSERT` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -x 1 foo -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar -step s1teardown: SELECT bdr.alter_node_set_conflict_resolver('node1', 'insert_exists', 'update_if_newer'); -alter_node_set_conflict_resolver - -t -step s2teardown: SELECT bdr.alter_node_set_conflict_resolver('node2', 'insert_exists', 'update_if_newer'); -alter_node_set_conflict_resolver - -t -``` - -## Test `two_node_dmlconflict_iu` - -``` -Parsed test spec with 3 sessions - -starting permutation: s3setup s1i s2w1 s2s s2u s2w s1w s1s s2s s3s s3teardown -``` - -We artificially introduce a 10 second replication delay between Node 1 -and Node 2, to force conflicts due to a different replay order. - -``` -step s3setup: -SELECT pglogical.alter_subscription_disable -('bdr_postgres_bdrgroup_node1_node3'); -UPDATE pglogical.subscription -SET sub_apply_delay = '10s' -WHERE sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable -('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -``` - -We insert a row into `node1`: - -``` -step s1i: INSERT INTO test_dmlconflict VALUES('x', 1, 'foo'); -``` - -We wait until the `INSERT` on `node1` is replicated to `node2`: - -``` -step s2w1: SELECT * from pg_sleep(1); -pg_sleep - - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -x 1 foo -``` - -On `node2` we update the row replicated from `node1`: - -``` -step s2u: UPDATE test_dmlconflict set a='z' where b=1; -``` - -We wait until the `UPDATE` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -Then we wait until the insert from `node1` is replicated to -`node3`: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -z 1 foo -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -z 1 foo -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -z 1 foo -step s3teardown: -SELECT pglogical.alter_subscription_disable -('bdr_postgres_bdrgroup_node1_node3'); -UPDATE pglogical.subscription -SET sub_apply_delay = '1s' -WHERE sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable -('bdr_postgres_bdrgroup_node1_node3'); -SELECT bdr.alter_node_set_conflict_resolver('node3', 'update_missing', 'insert_or_skip'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -alter_node_set_conflict_resolver - -t - -starting permutation: s3setup s3a s1s s1i s2w1 s2s s2u s2w s1w s1s s2s s3s s3teardown -``` - -We artificially introduce a 10 second replication delay between Node 1 -and Node 2, to force conflicts due to a different replay order. - -``` -step s3setup: -SELECT pglogical.alter_subscription_disable -('bdr_postgres_bdrgroup_node1_node3'); -UPDATE pglogical.subscription -SET sub_apply_delay = '10s' -WHERE sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable -('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -step s3a: SELECT bdr.alter_node_set_conflict_resolver('node3', 'update_missing', 'insert_or_error'); -alter_node_set_conflict_resolver - -t -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -We insert a row into `node1`: - -``` -step s1i: INSERT INTO test_dmlconflict VALUES('x', 1, 'foo'); -``` - -We wait until the `INSERT` on `node1` is replicated to `node2`: - -``` -step s2w1: SELECT * from pg_sleep(1); -pg_sleep - - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -x 1 foo -``` - -On `node2` we update the row replicated from `node1`: - -``` -step s2u: UPDATE test_dmlconflict set a='z' where b=1; -``` - -We wait until the `UPDATE` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -Then we wait until the insert from `node1` is replicated to -`node3`: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -z 1 foo -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -z 1 foo -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -z 1 foo -step s3teardown: -SELECT pglogical.alter_subscription_disable -('bdr_postgres_bdrgroup_node1_node3'); -UPDATE pglogical.subscription -SET sub_apply_delay = '1s' -WHERE sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable -('bdr_postgres_bdrgroup_node1_node3'); -SELECT bdr.alter_node_set_conflict_resolver('node3', 'update_missing', 'insert_or_skip'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -alter_node_set_conflict_resolver - -t -``` - -## Test `two_node_dmlconflict_id` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1i s2w1 s2s s2d s2w s1w s1s s2s s3s s3teardown -alter_subscription_enable - -t -``` - -We insert a row into a table on `node1`: - -``` -step s1i: INSERT INTO test_dmlconflict VALUES('x', 1, 'foo'); -``` - -We wait until the `INSERT` on `node1` is replicated to `node2`: - -``` -step s2w1: SELECT * from pg_sleep(1); -pg_sleep - - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -x 1 foo -``` - -On `node2` we delete the row replicated from `node1`: - -``` -step s2d: DELETE from test_dmlconflict where b=1; -``` - -We wait until the `DELETE` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -Now we wait until the insert from `node1` is replicated to -`node3` as well: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -x 1 foo -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -``` - -## Test `two_node_dmlconflict_it` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1i s2w1 s2s s2t s2w s1w s1s s2s s3s s3teardown -alter_subscription_enable - -t -``` - -We `INSERT` a row into a table on `node1`: - -``` -step s1i: INSERT INTO test_dmlconflict VALUES('y', 2, 'baz'); -``` - -We wait until the `INSERT` on `node1` is replicated to `node2`: - -``` -step s2w1: SELECT * from pg_sleep(1); -pg_sleep - - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -x 1 foo -y 2 baz -``` - -On `node2` we truncate the test table after the `INSERT` from `node1` is replicated: - -``` -step s2t: TRUNCATE test_dmlconflict; -``` - -We wait until the `TRUNCATE` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -Now we wait until the `INSERT` from `node1` is replicated to -`node3` as well: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -y 2 baz -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -``` - -## Test `two_node_dmlconflict_uu` - -``` -Parsed test spec with 2 sessions - -starting permutation: s1u s2u s1w s2w s1s s2s -``` - -We `UPDATE` a row from `node1`: - -``` -step s1u: UPDATE test_dmlconflict SET a = 'x' where b = 1; -``` - -We `UPDATE` a row from `node2` concurrently: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y' where b = 1; -``` - -We wait until the `UPDATE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -y 1 foo -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -y 1 foo - -starting permutation: s1a s2a s1u s2u s1w s2w s1s s2s s1teardown s2teardown -WARNING: setting update_origin_change to skip may result in loss of UPDATE -DETAIL: This occurs only if it cannot be confirmed that remote site has seen the local row -HINT: Use row_version conflict_detection and REPLICA IDENTITY FULL -step s1a: SELECT bdr.alter_node_set_conflict_resolver('node1', 'update_origin_change', 'skip'); -alter_node_set_conflict_resolver - -t -WARNING: setting update_origin_change to skip may result in loss of UPDATE -DETAIL: This occurs only if it cannot be confirmed that remote site has seen the local row -HINT: Use row_version conflict_detection and REPLICA IDENTITY FULL -step s2a: SELECT bdr.alter_node_set_conflict_resolver('node2', 'update_origin_change', 'skip'); -alter_node_set_conflict_resolver - -t -``` - -We `UPDATE` a row from `node1`: - -``` -step s1u: UPDATE test_dmlconflict SET a = 'x' where b = 1; -``` - -We `UPDATE` a row from `node2` concurrently: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y' where b = 1; -``` - -We wait until the `UPDATE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -x 1 foo -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -y 1 foo -step s1teardown: SELECT bdr.alter_node_set_conflict_resolver('node1', 'update_origin_change', 'update_if_newer'); -alter_node_set_conflict_resolver - -t -step s2teardown: SELECT bdr.alter_node_set_conflict_resolver('node2', 'update_origin_change', 'update_if_newer'); -alter_node_set_conflict_resolver - -t -``` - -## Test `two_node_dmlconflict_uu_replayorder` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1u s2w1 s2u s2w s1w s1s s2s s3s s3teardown -alter_subscription_enable - -t -step s1u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -We wait until the `UPDATE` on `node1` is replicated to `node2`: - -``` -step s2w1: SELECT * from pg_sleep(1); -pg_sleep - - -``` - -On `node2` we update the same row updated by `node1`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'z', b = '1', c = 'baz'; -``` - -We wait until the `UPDATE` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -Now we wait until the `UPDATE` from `node1` is replicated to -`node3` as well: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -z 1 baz -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -z 1 baz -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -z 1 baz -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -``` - -## Test `two_node_dmlconflict_ud` - -``` -Parsed test spec with 2 sessions - -starting permutation: s1d s2u s1w s2w s1s s2s s1slc -``` - -We delete the only row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -Now we wait until the commit on `node1` is updated on all nodes: - -``` -step s1w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -Now we wait until the commit on `node2` is replicated on all nodes: - -``` -step s2w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar -``` - -Read entries of the log_table at `node1`: - -``` -step s1slc: SELECT conflict_type, conflict_resolution, nspname, relname, key_tuple, apply_tuple FROM bdr.conflict_history ORDER BY local_time DESC LIMIT 1; -conflict_type conflict_resolutionnspname relname key_tuple apply_tuple - -update_recently_deletedskip public test_dmlconflict {"a":"y","b":1,"c":"bar"} - -starting permutation: s1urd s2urd s1d s2u s1w s2w s1s s2s s1urdteardown s2urdteardown -step s1urd: SELECT bdr.alter_node_set_conflict_resolver('node1', 'update_recently_deleted', 'insert_or_skip'); -alter_node_set_conflict_resolver - -t -step s2urd: SELECT bdr.alter_node_set_conflict_resolver('node2', 'update_recently_deleted', 'insert_or_skip'); -alter_node_set_conflict_resolver - -t -``` - -We delete the only row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -Now we wait until the commit on `node1` is updated on all nodes: - -``` -step s1w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -Now we wait until the commit on `node2` is replicated on all nodes: - -``` -step s2w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar -step s1urdteardown: SELECT bdr.alter_node_set_conflict_resolver('node1', 'update_recently_deleted', 'skip'); -alter_node_set_conflict_resolver - -t -step s2urdteardown: SELECT bdr.alter_node_set_conflict_resolver('node2', 'update_recently_deleted', 'skip'); -alter_node_set_conflict_resolver - -t - -starting permutation: s2u s1d s2w s1w s1s s2s -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -We delete the only row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -Now we wait until the commit on `node2` is replicated on all nodes: - -``` -step s2w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -Now we wait until the commit on `node1` is updated on all nodes: - -``` -step s1w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - - -starting permutation: s1dru s2dru s1d s2u s1w s2w s1s s2s s1druteardown s2druteardown -step s1dru: SELECT bdr.alter_node_set_conflict_resolver('node1', 'delete_recently_updated', 'update'); -alter_node_set_conflict_resolver - -t -step s2dru: SELECT bdr.alter_node_set_conflict_resolver('node2', 'delete_recently_updated', 'update'); -alter_node_set_conflict_resolver - -t -``` - -We delete the only row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -Now we wait until the commit on `node1` is updated on all nodes: - -``` -step s1w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -Now we wait until the commit on `node2` is replicated on all nodes: - -``` -step s2w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -step s1druteardown: SELECT bdr.alter_node_set_conflict_resolver('node1', 'delete_recently_updated', 'skip'); -alter_node_set_conflict_resolver - -t -step s2druteardown: SELECT bdr.alter_node_set_conflict_resolver('node2', 'delete_recently_updated', 'skip'); -alter_node_set_conflict_resolver - -t -``` - -## Test `two_node_dmlconflict_ud_replayorder` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1u s2d s2w s1w s1s s2s s3s s3teardown -alter_subscription_enable - -t -step s1u: UPDATE test_dmlconflict SET a = 'y', b = 1, c = 'bar'; -``` - -On `node2` we delete the same row updated by `node1`: - -``` -step s2d: DELETE FROM test_dmlconflict where b = 1; -``` - -We wait until the `DELETE` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -Now we wait until the `UPDATE` from `node1` is replicated to -`node3` as well: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -``` - -## Test `two_node_dmlconflict_ut` - -``` -Parsed test spec with 2 sessions - -starting permutation: s1t s2u s1w s2w s1s s2s -``` - -We truncate the table on `node1`: - -``` -step s1t: TRUNCATE test_dmlconflict; -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -We wait until the `TRUNCATE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - - -starting permutation: s2u s1t s2w s1w s1s s2s -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -We truncate the table on `node1`: - -``` -step s1t: TRUNCATE test_dmlconflict; -``` - -We wait until the `UPDATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c -``` - -## Test `two_node_dmlconflict_dd` - -``` -Parsed test spec with 2 sessions - -starting permutation: s1d s2d s1w s2w s1s s2s -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We delete same row from `node2` concurrently: - -``` -step s2d: DELETE FROM test_dmlconflict where b = 1; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `DELETE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c -``` - -## Test `two_node_dmlconflict_dt` - -``` -Parsed test spec with 2 sessions - -starting permutation: s1d s2t s1w s2w s1s s2s -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We truncate test_dmlconflict on `node2`: - -``` -step s2t: TRUNCATE test_dmlconflict; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - - -starting permutation: s2t s1d s1w s2w s1s s2s -``` - -We truncate test_dmlconflict on `node2`: - -``` -step s2t: TRUNCATE test_dmlconflict; -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c -``` - -## Test `two_node_dmlconflict_tt` - -``` -Parsed test spec with 2 sessions - -starting permutation: s1t s2t s1w s2w s1s s2s -``` - -We truncate the table on `node1`: - -``` -step s1t: TRUNCATE test_dmlconflict; -step s2t: TRUNCATE test_dmlconflict; -``` - -We wait until `TRUNCATE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until `TRUNCATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c -``` - -## Test `three_node_dmlconflict_iii` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1i s2i s3i s1w s2w s3w s1s s2s s3s -``` - -We insert a row into `node1`: - -``` -step s1i: INSERT INTO test_dmlconflict VALUES('x', 1, 'foo'); -``` - -We insert a row with the same primary key into `node2`: - -``` -step s2i: INSERT INTO test_dmlconflict VALUES('y', 1, 'bar'); -``` - -We insert a row with the same primary key into `node3`: - -``` -step s3i: INSERT INTO test_dmlconflict VALUES('z', 1, 'baz'); -``` - -We wait until `INSERT` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until `INSERT` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `INSERT` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -z 1 baz -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -z 1 baz -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -z 1 baz -``` - -## Test `three_node_dmlconflict_iiu` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1i s2w1 s2s s2u s3i s2w s1w s3w s1s s2s s3s s3teardown -alter_subscription_enable - -t -``` - -We insert a row into a table on `node1`: - -``` -step s1i: INSERT INTO test_dmlconflict VALUES('x', 1, 'foo'); -``` - -We wait until the `INSERT` on `node1` is replicated to `node2`: - -``` -step s2w1: SELECT * from pg_sleep(1); -pg_sleep - - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -x 1 foo -``` - -On `node2` we update the same row inserted by `node1`: - -``` -step s2u: UPDATE test_dmlconflict set a='z' where b=1; -``` - -We insert a row with same primary key on `node3` before `INSERT` from -node1\` is replicated: - -``` -step s3i: INSERT INTO test_dmlconflict VALUES('y', 1, 'baz'); -``` - -We wait until the `UPDATE` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -Now we wait until the insert from `node1` is replicated to -`node3` as well: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `INSERT` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -y 1 baz -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -y 1 baz -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -y 1 baz -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -``` - -## Test `three_node_dmlconflict_iid` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1i s2w1 s2s s2d s3i s2w s1w s3w s1s s2s s3s s3teardown -alter_subscription_enable - -t -``` - -We insert a row into a table on `node1`: - -``` -step s1i: INSERT INTO test_dmlconflict VALUES('x', 1, 'foo'); -``` - -We wait until the `INSERT` on `node1` is replicated to `node2`: - -``` -step s2w1: SELECT * from pg_sleep(1); -pg_sleep - - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -x 1 foo -``` - -On `node2` we delete the row replicated from `node1`: - -``` -step s2d: DELETE from test_dmlconflict where b=1; -``` - -We insert a row with same primary key on `node3` before `INSERT` from `node1` is replicated: - -``` -step s3i: INSERT INTO test_dmlconflict VALUES('y', 1, 'baz'); -``` - -We wait until the `DELETE` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -Now we wait until the insert from `node1` is replicated to -`node3` as well: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `INSERT` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -y 1 baz -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -y 1 baz -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -y 1 baz -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -``` - -## Test `three_node_dmlconflict_iit` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1i s2w1 s2s s2t s3i s2w s1w s3w s1s s2s s3s s3teardown -alter_subscription_enable - -t -``` - -We insert a row into a table on `node1`: - -``` -step s1i: INSERT INTO test_dmlconflict VALUES('x', 1, 'foo'); -``` - -We wait until the `INSERT` on `node1` is replicated to `node2`: - -``` -step s2w1: SELECT * from pg_sleep(1); -pg_sleep - - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -z 2 bar -x 1 foo -``` - -On `node2` we truncate the test table after `INSERT` from `node1` is replicated: - -``` -step s2t: TRUNCATE test_dmlconflict; -``` - -We insert a row with the same primary key on `node3` before the `INSERT` from -`node1` is replicated: - -``` -step s3i: INSERT INTO test_dmlconflict VALUES('y', 1, 'baz'); -``` - -We wait until the `TRUNCATE` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -Now we wait until the insert from `node1` is replicated to -`node3` as well: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `INSERT` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -y 1 baz -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -y 1 baz -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -x 1 foo -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -``` - -## Test `three_node_dmlconflict_uuu` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1u s2u s3u s1w s2w s3w s1s s2s s3s -``` - -We `UPDATE` a row from `node1`: - -``` -step s1u: UPDATE test_dmlconflict SET a = 'x', b = '1', c = 'foo'; -``` - -We `UPDATE` a row from `node2` concurrently: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -We `UPDATE` a row from `node3` concurrently: - -``` -step s3u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'baz'; -``` - -We wait until the `UPDATE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -y 1 baz -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -y 1 baz -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -y 1 baz -``` - -## Test `three_node_dmlconflict_uud` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1u s2w1 s2u s3d s1w s2w s3w s1s s2s s3s s3teardown -alter_subscription_enable - -t -step s1u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'baz'; -``` - -We wait until the `UPDATE` on `node1` is replicated to `node2`: - -``` -step s2w1: SELECT * from pg_sleep(1); -pg_sleep - - -``` - -On `node2` we update the same row updated by `node1`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'z', b = '1', c = 'bar'; -``` - -We `DELETE` the row on `node3` before `update` from `node1` arrives: - -``` -step s3d: DELETE FROM test_dmlconflict; -``` - -Now we wait until the `UPDATE` from `node1` is replicated to -`node3` as well: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `DELETE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -``` - -## Test `three_node_dmlconflict_uut` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1u s2u s3t s1w s2w s3w s1s s2s s3s -``` - -We update a row on `node1`: - -``` -step s1u: UPDATE test_dmlconflict SET a = 'z', b = '1', c = 'baz'; -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -`TRUNCATE` the table from `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We wait until the `UPDATE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the ```TRUNCATE`` on ```node3\` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar - -starting permutation: s1u s3t s2u s1w s2w s3w s1s s2s s3s -``` - -We update a row on `node1`: - -``` -step s1u: UPDATE test_dmlconflict SET a = 'z', b = '1', c = 'baz'; -``` - -`TRUNCATE` the table from `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -We wait until the `UPDATE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the ```TRUNCATE`` on ```node3\` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar - -starting permutation: s3t s2u s1u s1w s2w s3w s1s s2s s3s -``` - -`TRUNCATE` the table from `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -We update a row on `node1`: - -``` -step s1u: UPDATE test_dmlconflict SET a = 'z', b = '1', c = 'baz'; -``` - -We wait until the `UPDATE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the ```TRUNCATE`` on ```node3\` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -z 1 baz -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -z 1 baz -``` - -## Test `three_node_dmlconflict_udt` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1d s2u s3t s1w s2w s3w s1s s2s s3s s1teardown s3teardown s1tear s1w -alter_subscription_enable - -t -alter_subscription_enable - -t -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = 1, c = 'bar' where b = 1; -``` - -We truncate the table on `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar -step s1teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_regression_bdrgroup_node3_node1'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_regression_bdrgroup_node3_node1'; -SELECT pglogical.alter_subscription_enable('bdr_regression_bdrgroup_node3_node1'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -step s1tear: -DROP TABLE IF EXISTS test_dmlconflict; - -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - - -starting permutation: s2u s1d s3t s1w s2w s3w s1s s2s s3s s1teardown s3teardown s1tear s1w -alter_subscription_enable - -t -alter_subscription_enable - -t -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = 1, c = 'bar' where b = 1; -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We truncate the table on `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -step s1teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_regression_bdrgroup_node3_node1'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_regression_bdrgroup_node3_node1'; -SELECT pglogical.alter_subscription_enable('bdr_regression_bdrgroup_node3_node1'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -step s1tear: -DROP TABLE IF EXISTS test_dmlconflict; - -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - - -starting permutation: s2u s3t s1d s1w s2w s3w s1s s2s s3s s1teardown s3teardown s1tear s1w -alter_subscription_enable - -t -alter_subscription_enable - -t -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = 1, c = 'bar' where b = 1; -``` - -We truncate the table on `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -step s1teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_regression_bdrgroup_node3_node1'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_regression_bdrgroup_node3_node1'; -SELECT pglogical.alter_subscription_enable('bdr_regression_bdrgroup_node3_node1'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -step s1tear: -DROP TABLE IF EXISTS test_dmlconflict; - -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - - -starting permutation: s1d s3t s2u s1w s2w s3w s1s s2s s3s s1teardown s3teardown s1tear s1w -alter_subscription_enable - -t -alter_subscription_enable - -t -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We truncate the table on `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = 1, c = 'bar' where b = 1; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar -step s1teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_regression_bdrgroup_node3_node1'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_regression_bdrgroup_node3_node1'; -SELECT pglogical.alter_subscription_enable('bdr_regression_bdrgroup_node3_node1'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -step s1tear: -DROP TABLE IF EXISTS test_dmlconflict; - -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - - -starting permutation: s3t s2u s1d s1w s2w s3w s1s s2s s3s s1teardown s3teardown s1tear s1w -alter_subscription_enable - -t -alter_subscription_enable - -t -``` - -We truncate the table on `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = 1, c = 'bar' where b = 1; -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -step s1teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_regression_bdrgroup_node3_node1'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_regression_bdrgroup_node3_node1'; -SELECT pglogical.alter_subscription_enable('bdr_regression_bdrgroup_node3_node1'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -step s1tear: -DROP TABLE IF EXISTS test_dmlconflict; - -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - - -starting permutation: s3t s1d s2u s1w s2w s3w s1s s2s s3s s1teardown s3teardown s1tear s1w -alter_subscription_enable - -t -alter_subscription_enable - -t -``` - -We truncate the table on `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = 1, c = 'bar' where b = 1; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar -step s1teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_regression_bdrgroup_node3_node1'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_regression_bdrgroup_node3_node1'; -SELECT pglogical.alter_subscription_enable('bdr_regression_bdrgroup_node3_node1'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -step s1tear: -DROP TABLE IF EXISTS test_dmlconflict; - -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn -``` - -## Test `three_node_dmlconflict_duu` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1d s2u s3u s1w s2w s3w s1s s2s s3s -``` - -We delete the only row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict; -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -We update the same row on `node3`: - -``` -step s3u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'baz'; -``` - -now we wait until the commit on `node1` is updated on all nodes: - -``` -step s1w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -now we wait until the commit on `node2` is replicated on all nodes: - -``` -step s2w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -now we wait until the commit on `node3` is replicated on all nodes: - -``` -step s3w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -y 1 baz -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -y 1 baz - -starting permutation: s2u s1d s3u s2w s1w s3w s1s s2s s3s -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -We delete the only row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict; -``` - -We update the same row on `node3`: - -``` -step s3u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'baz'; -``` - -now we wait until the commit on `node2` is replicated on all nodes: - -``` -step s2w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -now we wait until the commit on `node1` is updated on all nodes: - -``` -step s1w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -now we wait until the commit on `node3` is replicated on all nodes: - -``` -step s3w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -y 1 baz - -starting permutation: s2u s3u s1d s2w s3w s1w s1s s2s s3s -``` - -We update the same row on `node2`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -We update the same row on `node3`: - -``` -step s3u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'baz'; -``` - -We delete the only row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict; -``` - -now we wait until the commit on `node2` is replicated on all nodes: - -``` -step s2w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -now we wait until the commit on `node3` is replicated on all nodes: - -``` -step s3w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -now we wait until the commit on `node1` is updated on all nodes: - -``` -step s1w: select bdr.wait_slot_confirm_lsn(null,null); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c -``` - -## Test `three_node_dmlconflict_ddd` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1d s2d s3d s1w s2w s3w s1s s2s s3s -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict; -``` - -We delete a row from `node2` concurrently: - -``` -step s2d: DELETE FROM test_dmlconflict; -``` - -We delete a row from `node3` concurrently: - -``` -step s3d: DELETE FROM test_dmlconflict; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `DELETE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `DELETE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c -``` - -## Test `three_node_dmlconflict_ddt` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1d s2d s3t s1w s2w s3w s1s s2s s3s -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We delete a row from `node2`: - -``` -step s2d: DELETE FROM test_dmlconflict where b = 2; -``` - -We truncate test_dmlconclict on `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `DELETE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - - -starting permutation: s2d s1d s3t s1w s2w s3w s1s s2s s3s -``` - -We delete a row from `node2`: - -``` -step s2d: DELETE FROM test_dmlconflict where b = 2; -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We truncate test_dmlconclict on `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `DELETE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - - -starting permutation: s2d s3t s1d s1w s2w s3w s1s s2s s3s -``` - -We delete a row from `node2`: - -``` -step s2d: DELETE FROM test_dmlconflict where b = 2; -``` - -We truncate test_dmlconclict on `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `DELETE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - - -starting permutation: s1d s3t s2d s1w s2w s3w s1s s2s s3s -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We truncate test_dmlconclict on `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We delete a row from `node2`: - -``` -step s2d: DELETE FROM test_dmlconflict where b = 2; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `DELETE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - - -starting permutation: s3t s2d s1d s1w s2w s3w s1s s2s s3s -``` - -We truncate test_dmlconclict on `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We delete a row from `node2`: - -``` -step s2d: DELETE FROM test_dmlconflict where b = 2; -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `DELETE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - - -starting permutation: s3t s1d s2d s1w s2w s3w s1s s2s s3s -``` - -We truncate test_dmlconclict on `node3`: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -We delete a row from `node1`: - -``` -step s1d: DELETE FROM test_dmlconflict where b = 1; -``` - -We delete a row from `node2`: - -``` -step s2d: DELETE FROM test_dmlconflict where b = 2; -``` - -We wait until the `DELETE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `DELETE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c -``` - -## Test `three_node_dmlconflict_tuu` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1u s2w1 s2u s3t s1w s2w s3w s1s s2s s3s s3teardown -alter_subscription_enable - -t -step s1u: UPDATE test_dmlconflict SET a = 'z', b = '1', c = 'baz'; -``` - -We wait until the `UPDATE` on `node1` is replicated to `node2`: - -``` -step s2w1: SELECT * from pg_sleep(1); -pg_sleep - - -``` - -On `node2` we update the same row updated by `node1`: - -``` -step s2u: UPDATE test_dmlconflict SET a = 'y', b = '1', c = 'bar'; -``` - -We `TRUNCATE` the table on `node3` before `update` from `node1` arrives: - -``` -step s3t: TRUNCATE test_dmlconflict; -``` - -Now we wait until the `UPDATE` from `node1` is replicated to -`node3` as well: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `UPDATE` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c - -y 1 bar -step s3teardown: -BEGIN; -SELECT pglogical.alter_subscription_disable('bdr_postgres_bdrgroup_node1_node3'); -END; -UPDATE pglogical.subscription set sub_apply_delay = '1s' where sub_name = 'bdr_postgres_bdrgroup_node1_node3'; -SELECT pglogical.alter_subscription_enable('bdr_postgres_bdrgroup_node1_node3'); - -alter_subscription_disable - -t -alter_subscription_enable - -t -``` - -## Test `three_node_dmlconflict_ttt` - -``` -Parsed test spec with 3 sessions - -starting permutation: s1t s2t s3t s1w s2w s3w s1s s2s s3s -``` - -We truncate the table on `node1`: - -``` -step s1t: TRUNCATE test_dmlconflict; -step s2t: TRUNCATE test_dmlconflict; -step s3t: TRUNCATE test_dmlconflict; -``` - -We wait until the `TRUNCATE` on `node1` is replicated to all other nodes: - -``` -step s1w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node2` is replicated to all other nodes: - -``` -step s2w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -We wait until the `TRUNCATE` on `node3` is replicated to all other nodes: - -``` -step s3w: SELECT bdr.wait_slot_confirm_lsn(NULL,NULL); -wait_slot_confirm_lsn - - -``` - -State of `node1`: - -``` -step s1s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node2`: - -``` -step s2s: SELECT * FROM test_dmlconflict; -a b c - -``` - -State of `node3`: - -``` -step s3s: SELECT * FROM test_dmlconflict; -a b c -``` +