mirror of https://github.com/citusdata/citus.git
113 lines
2.9 KiB
Ruby
113 lines
2.9 KiB
Ruby
setup
|
|
{
|
|
CREATE TABLE test_insert_concurrency (a int, b int) USING columnar;
|
|
|
|
CREATE OR REPLACE FUNCTION columnar_relation_storageid(relid oid) RETURNS bigint
|
|
LANGUAGE C STABLE STRICT
|
|
AS 'citus', $$columnar_relation_storageid$$;
|
|
}
|
|
|
|
teardown
|
|
{
|
|
DROP TABLE IF EXISTS test_insert_concurrency CASCADE;
|
|
}
|
|
|
|
session "s1"
|
|
|
|
step "s1-begin"
|
|
{
|
|
BEGIN;
|
|
}
|
|
|
|
step "s1-insert"
|
|
{
|
|
INSERT INTO test_insert_concurrency SELECT i, 2 * i FROM generate_series(1, 3) i;
|
|
}
|
|
|
|
step "s1-insert-10000-rows"
|
|
{
|
|
INSERT INTO test_insert_concurrency SELECT i, 2 * i FROM generate_series(1, 10000) i;
|
|
}
|
|
|
|
step "s1-copy"
|
|
{
|
|
COPY test_insert_concurrency(a) FROM PROGRAM 'seq 11 13';
|
|
}
|
|
|
|
step "s1-select"
|
|
{
|
|
SELECT * FROM test_insert_concurrency ORDER BY a;
|
|
}
|
|
|
|
step "s1-truncate"
|
|
{
|
|
TRUNCATE test_insert_concurrency;
|
|
}
|
|
|
|
step "s1-verify-metadata"
|
|
{
|
|
WITH test_insert_concurrency_stripes AS (
|
|
SELECT first_row_number, stripe_num, row_count
|
|
FROM columnar.stripe a, pg_class b
|
|
WHERE columnar_relation_storageid(b.oid)=a.storage_id AND
|
|
relname = 'test_insert_concurrency'
|
|
)
|
|
SELECT
|
|
-- verify that table has two stripes ..
|
|
count(*) = 2 AND
|
|
-- .. and those stripes look like:
|
|
sum(case when stripe_num = 1 AND first_row_number = 150001 AND row_count = 3 then 1 end) = 1 AND
|
|
sum(case when stripe_num = 2 AND first_row_number = 1 AND row_count = 10000 then 1 end) = 1
|
|
AS stripe_metadata_for_test_insert_concurrency_ok
|
|
FROM test_insert_concurrency_stripes;
|
|
}
|
|
|
|
step "s1-commit"
|
|
{
|
|
COMMIT;
|
|
}
|
|
|
|
session "s2"
|
|
|
|
step "s2-begin"
|
|
{
|
|
BEGIN;
|
|
}
|
|
|
|
step "s2-begin-repeatable"
|
|
{
|
|
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
|
}
|
|
|
|
step "s2-insert"
|
|
{
|
|
INSERT INTO test_insert_concurrency SELECT i, 2 * i FROM generate_series(4, 6) i;
|
|
}
|
|
|
|
step "s2-select"
|
|
{
|
|
SELECT * FROM test_insert_concurrency ORDER BY a;
|
|
}
|
|
|
|
step "s2-commit"
|
|
{
|
|
COMMIT;
|
|
}
|
|
|
|
// writes shouldn't block writes or reads
|
|
permutation "s1-begin" "s2-begin" "s1-insert" "s2-insert" "s1-select" "s2-select" "s1-commit" "s2-commit" "s1-select"
|
|
|
|
// copy vs insert
|
|
permutation "s1-begin" "s2-begin" "s1-copy" "s2-insert" "s1-select" "s2-select" "s1-commit" "s2-commit" "s1-select"
|
|
|
|
// insert vs copy
|
|
permutation "s1-begin" "s2-begin" "s2-insert" "s1-copy" "s1-select" "s2-select" "s1-commit" "s2-commit" "s1-select"
|
|
|
|
# insert vs insert
|
|
# Start inserting rows in session 1, reserve first_row_number to be 1 for session 1 but commit session 2 before session 1.
|
|
# Then verify that while the stripe written by session 2 has the greater first_row_number, stripe written by session 1 has
|
|
# the greater stripe_num. This is because, we reserve stripe_num and first_row_number at different times.
|
|
permutation "s1-truncate" "s1-begin" "s1-insert-10000-rows" "s2-begin" "s2-insert" "s2-commit" "s1-commit" "s1-verify-metadata"
|
|
|
|
permutation "s1-begin" "s2-begin-repeatable" "s1-insert" "s2-insert" "s2-select" "s1-commit" "s2-select" "s2-commit"
|