blob: f52c6890dd0060e33c2d8db1cb5971c546979aa9 [file] [log] [blame]
0:CREATE RESOURCE QUEUE rq_concurrency_test WITH (active_statements = 1);
CREATE
0:CREATE role role_concurrency_test RESOURCE QUEUE rq_concurrency_test;
CREATE
1:SET role role_concurrency_test;
SET
1:BEGIN;
BEGIN
1:DECLARE c1 CURSOR FOR SELECT 1;
DECLARE
2:SET role role_concurrency_test;
SET
2:PREPARE fooplan AS SELECT 1;
PREPARE
2&:EXECUTE fooplan; <waiting ...>
-- EXECUTE statement(cached plan) will be blocked when the concurrency limit of the resource queue is reached.
0:SELECT rsqcountvalue FROM gp_toolkit.gp_resqueue_status WHERE rsqname='rq_concurrency_test';
rsqcountvalue
---------------
1
(1 row)
0:SELECT wait_event_type, wait_event from pg_stat_activity where query = 'EXECUTE fooplan;';
wait_event_type | wait_event
-----------------+---------------
ResourceQueue | ResourceQueue
(1 row)
-- This should also block.
--
-- We used to have a bug during 9.6 merge where selecting from pg_locks caused
-- a crash, because we didn't set all the fields in the PROCLOCK struct
-- correctly. That only manifested when there were two queries blocked.
3:SET role role_concurrency_test;
SET
3:PREPARE fooplan AS SELECT 1;
PREPARE
3&:EXECUTE fooplan; <waiting ...>
-- Check pg_stat_activity and pg_locks.
0:SELECT wait_event_type, wait_event from pg_stat_activity where query = 'EXECUTE fooplan;';
wait_event_type | wait_event
-----------------+---------------
ResourceQueue | ResourceQueue
ResourceQueue | ResourceQueue
(2 rows)
0:SELECT granted, locktype, mode FROM pg_locks where locktype = 'resource queue' and pid != pg_backend_pid();
granted | locktype | mode
---------+----------------+---------------
f | resource queue | ExclusiveLock
t | resource queue | ExclusiveLock
f | resource queue | ExclusiveLock
(3 rows)
1:END;
END
2<: <... completed>
?column?
----------
1
(1 row)
2:END;
END
3<: <... completed>
?column?
----------
1
(1 row)
3:END;
END
-- Sanity check: Ensure that all locks were released.
0:SELECT granted, locktype, mode FROM pg_locks where locktype = 'resource queue' and pid != pg_backend_pid();
granted | locktype | mode
---------+----------+------
(0 rows)
-- Sanity check: Ensure that the resource queue is now empty.
0: SELECT rsqcountlimit, rsqcountvalue from pg_resqueue_status WHERE rsqname = 'rq_concurrency_test';
rsqcountlimit | rsqcountvalue
---------------+---------------
1 | 0
(1 row)
-- Introduce a holdable cursor.
4:SET role role_concurrency_test;
SET
4:DECLARE c_hold CURSOR WITH HOLD FOR SELECT 1;
DECLARE
-- Sanity check: The holdable cursor should be accounted for in pg_locks.
0:SELECT granted, locktype, mode FROM pg_locks where locktype = 'resource queue' and pid != pg_backend_pid();
granted | locktype | mode
---------+----------------+---------------
t | resource queue | ExclusiveLock
(1 row)
4:CLOSE c_hold;
CLOSE
-- Sanity check: Ensure that all locks were released.
0:SELECT granted, locktype, mode FROM pg_locks where locktype = 'resource queue' and pid != pg_backend_pid();
granted | locktype | mode
---------+----------+------
(0 rows)
-- Sanity check: Ensure that the resource queue is now empty.
0: SELECT rsqcountlimit, rsqcountvalue from pg_resqueue_status WHERE rsqname = 'rq_concurrency_test';
rsqcountlimit | rsqcountvalue
---------------+---------------
1 | 0
(1 row)
0:DROP role role_concurrency_test;
DROP
0:DROP RESOURCE QUEUE rq_concurrency_test;
DROP