mirror of https://github.com/citusdata/citus.git
186 lines
7.2 KiB
Ruby
186 lines
7.2 KiB
Ruby
setup
|
|
{
|
|
SET citus.shard_count to 2;
|
|
SET citus.shard_replication_factor to 1;
|
|
SELECT setval('pg_dist_shardid_seq',
|
|
CASE WHEN nextval('pg_dist_shardid_seq') > 1599999 OR nextval('pg_dist_shardid_seq') < 1500072
|
|
THEN 1500072
|
|
ELSE nextval('pg_dist_shardid_seq')-2
|
|
END);
|
|
|
|
CREATE TABLE isolation_table (id int PRIMARY KEY, value int);
|
|
SELECT create_distributed_table('isolation_table', 'id');
|
|
|
|
-- different colocation id
|
|
CREATE TABLE isolation_table2 (id smallint PRIMARY KEY, value int);
|
|
SELECT create_distributed_table('isolation_table2', 'id');
|
|
}
|
|
|
|
teardown
|
|
{
|
|
DROP TABLE isolation_table;
|
|
DROP TABLE isolation_table2;
|
|
}
|
|
|
|
session "s1"
|
|
|
|
step "s1-begin"
|
|
{
|
|
BEGIN;
|
|
|
|
-- the tests are written with the logic where single shard SELECTs
|
|
-- do not to open transaction blocks
|
|
SET citus.select_opens_transaction_block TO false;
|
|
}
|
|
|
|
// cache all placements
|
|
step "s1-load-cache"
|
|
{
|
|
TRUNCATE isolation_table;
|
|
TRUNCATE isolation_table2;
|
|
}
|
|
|
|
step "s1-insert"
|
|
{
|
|
INSERT INTO isolation_table VALUES (5, 10);
|
|
INSERT INTO isolation_table2 VALUES (5, 10);
|
|
}
|
|
|
|
step "s1-update"
|
|
{
|
|
UPDATE isolation_table SET value = 5 WHERE id = 5;
|
|
}
|
|
|
|
step "s1-update-complex"
|
|
{
|
|
UPDATE isolation_table SET value = 5 WHERE id IN (
|
|
SELECT max(id) FROM isolation_table
|
|
);
|
|
}
|
|
|
|
step "s1-delete"
|
|
{
|
|
DELETE FROM isolation_table WHERE id = 5;
|
|
}
|
|
|
|
step "s1-select"
|
|
{
|
|
SELECT count(*) FROM isolation_table WHERE id = 5;
|
|
}
|
|
|
|
step "s1-copy"
|
|
{
|
|
COPY isolation_table FROM PROGRAM 'echo "1,1\n2,2\n3,3\n4,4\n5,5"' WITH CSV;
|
|
}
|
|
|
|
step "s1-isolate-tenant-same-coloc"
|
|
{
|
|
SELECT isolate_tenant_to_new_shard('isolation_table', 2, shard_transfer_mode => 'force_logical');
|
|
}
|
|
|
|
step "s1-isolate-tenant-same-coloc-blocking"
|
|
{
|
|
SELECT isolate_tenant_to_new_shard('isolation_table', 2, shard_transfer_mode => 'block_writes');
|
|
}
|
|
|
|
step "s1-isolate-tenant-no-same-coloc"
|
|
{
|
|
SELECT isolate_tenant_to_new_shard('isolation_table2', 2, shard_transfer_mode => 'force_logical');
|
|
}
|
|
|
|
step "s1-isolate-tenant-no-same-coloc-blocking"
|
|
{
|
|
SELECT isolate_tenant_to_new_shard('isolation_table2', 2, shard_transfer_mode => 'block_writes');
|
|
}
|
|
|
|
step "s1-commit"
|
|
{
|
|
COMMIT;
|
|
}
|
|
|
|
session "s2"
|
|
|
|
step "s2-begin"
|
|
{
|
|
BEGIN;
|
|
}
|
|
|
|
step "s2-isolate-tenant"
|
|
{
|
|
SELECT isolate_tenant_to_new_shard('isolation_table', 5, shard_transfer_mode => 'force_logical');
|
|
}
|
|
|
|
step "s2-commit"
|
|
{
|
|
COMMIT;
|
|
}
|
|
|
|
step "s2-print-cluster"
|
|
{
|
|
-- row count per shard
|
|
SELECT
|
|
nodeport, shardid, success, result
|
|
FROM
|
|
run_command_on_placements('isolation_table', 'select count(*) from %s')
|
|
ORDER BY
|
|
nodeport, shardid;
|
|
|
|
-- rows
|
|
SELECT id, value FROM isolation_table ORDER BY id, value;
|
|
}
|
|
|
|
session "s3"
|
|
|
|
// this advisory lock with (almost) random values are only used
|
|
// for testing purposes. For details, check Citus' logical replication
|
|
// source code
|
|
step "s3-acquire-advisory-lock"
|
|
{
|
|
SELECT pg_advisory_lock(44000, 55152);
|
|
}
|
|
|
|
step "s3-release-advisory-lock"
|
|
{
|
|
SELECT pg_advisory_unlock(44000, 55152);
|
|
}
|
|
|
|
// Even if we do not block shard split copy operations, we eventually have to block concurrent sessions during metadata operations (tiny amount of time)
|
|
// To prevent concurrent DML from being blocked by metadata operations, we take the advisory lock from another dummy session, and let the concurrent DML
|
|
// executes concurrently with shard split copy. Just before committing, we release the advisory lock from the dummy session to allow all the sessions to finish.
|
|
// s3 takes an advisory lock before s2 takes it (we take the same lock for shard movement only during isolation tests) =>
|
|
// s1 can execute its DML command concurrently with s2 shard isolation =>
|
|
// s3 releases the advisory lock so that s2 can finish the transaction
|
|
|
|
// run tenant isolation while concurrently performing an DML
|
|
// we expect DML queries of s2 to succeed without being blocked.
|
|
permutation "s1-load-cache" "s1-insert" "s3-acquire-advisory-lock" "s1-begin" "s1-select" "s2-begin" "s2-isolate-tenant" "s1-update" "s1-commit" "s3-release-advisory-lock" "s2-commit" "s2-print-cluster"
|
|
permutation "s1-load-cache" "s1-insert" "s3-acquire-advisory-lock" "s1-begin" "s1-select" "s2-begin" "s2-isolate-tenant" "s1-delete" "s1-commit" "s3-release-advisory-lock" "s2-commit" "s2-print-cluster"
|
|
permutation "s1-load-cache" "s1-insert" "s3-acquire-advisory-lock" "s1-begin" "s1-select" "s2-begin" "s2-isolate-tenant" "s1-update-complex" "s1-commit" "s3-release-advisory-lock" "s2-commit" "s2-print-cluster"
|
|
permutation "s1-load-cache" "s3-acquire-advisory-lock" "s1-begin" "s1-select" "s2-begin" "s2-isolate-tenant" "s1-insert" "s1-commit" "s3-release-advisory-lock" "s2-commit" "s2-print-cluster"
|
|
permutation "s1-load-cache" "s3-acquire-advisory-lock" "s1-begin" "s1-select" "s2-begin" "s2-isolate-tenant" "s1-copy" "s1-commit" "s3-release-advisory-lock" "s2-commit" "s2-print-cluster"
|
|
|
|
// the same tests without loading the cache at first
|
|
permutation "s1-insert" "s3-acquire-advisory-lock" "s1-begin" "s1-select" "s2-begin" "s2-isolate-tenant" "s1-update" "s1-commit" "s3-release-advisory-lock" "s2-commit" "s2-print-cluster"
|
|
permutation "s1-insert" "s3-acquire-advisory-lock" "s1-begin" "s1-select" "s2-begin" "s2-isolate-tenant" "s1-delete" "s1-commit" "s3-release-advisory-lock" "s2-commit" "s2-print-cluster"
|
|
permutation "s1-insert" "s3-acquire-advisory-lock" "s1-begin" "s1-select" "s2-begin" "s2-isolate-tenant" "s1-update-complex" "s1-commit" "s3-release-advisory-lock" "s2-commit" "s2-print-cluster"
|
|
permutation "s3-acquire-advisory-lock" "s1-begin" "s1-select" "s2-begin" "s2-isolate-tenant" "s1-insert" "s1-commit" "s3-release-advisory-lock" "s2-commit" "s2-print-cluster"
|
|
permutation "s3-acquire-advisory-lock" "s1-begin" "s1-select" "s2-begin" "s2-isolate-tenant" "s1-copy" "s1-commit" "s3-release-advisory-lock" "s2-commit" "s2-print-cluster"
|
|
|
|
// concurrent nonblocking tenant isolations with the same colocation id are not allowed
|
|
permutation "s1-load-cache" "s1-insert" "s3-acquire-advisory-lock" "s2-isolate-tenant" "s1-isolate-tenant-same-coloc" "s3-release-advisory-lock" "s2-print-cluster"
|
|
|
|
// concurrent blocking and nonblocking tenant isolations with the same colocation id are not allowed
|
|
permutation "s1-load-cache" "s1-insert" "s3-acquire-advisory-lock" "s2-isolate-tenant" "s1-isolate-tenant-same-coloc-blocking" "s3-release-advisory-lock" "s2-print-cluster"
|
|
|
|
// concurrent nonblocking tenant isolations in different transactions are not allowed
|
|
permutation "s1-load-cache" "s1-insert" "s3-acquire-advisory-lock" "s2-isolate-tenant" "s1-isolate-tenant-no-same-coloc" "s3-release-advisory-lock" "s2-print-cluster"
|
|
|
|
// concurrent nonblocking tenant isolations in the same transaction are not allowed
|
|
permutation "s1-load-cache" "s1-insert" "s3-acquire-advisory-lock" "s2-begin" "s2-isolate-tenant" "s1-isolate-tenant-no-same-coloc" "s3-release-advisory-lock" "s2-commit" "s2-print-cluster"
|
|
|
|
// concurrent blocking and nonblocking tenant isolations with different colocation ids in different transactions are allowed
|
|
permutation "s1-load-cache" "s1-insert" "s3-acquire-advisory-lock" "s2-isolate-tenant" "s1-isolate-tenant-no-same-coloc-blocking" "s3-release-advisory-lock" "s2-print-cluster"
|
|
|
|
// concurrent blocking and nonblocking tenant isolations with different colocation ids in the same transaction are allowed
|
|
permutation "s1-load-cache" "s1-insert" "s3-acquire-advisory-lock" "s2-isolate-tenant" "s1-isolate-tenant-no-same-coloc-blocking" "s3-release-advisory-lock" "s2-print-cluster"
|