blob: 6a9ee3b460d03788b1dee3df47dbf40544e9d45e [file] [log] [blame]
-- This test validates that a reader process waits if lock is not
-- available. There used to be a bug where reader didn't wait even if
-- lock was held by some other session.
-- setup
CREATE or REPLACE FUNCTION check_readers_are_blocked ()
RETURNS bool AS
$$
declare
retries int; /* in func */
begin
retries := 1200; /* in func */
loop
if (SELECT count(*) > 0 as reader_waits from
pg_locks l join pg_stat_activity a on a.pid = l.pid
and a.query like '%reader_waits_for_lock_table%'
and not a.pid = pg_backend_pid()
and l.granted = false and l.mppiswriter = false) then
return true; /* in func */
end if; /* in func */
if retries <= 0 then
return false; /* in func */
end if; /* in func */
perform pg_sleep(0.1); /* in func */
perform pg_stat_clear_snapshot(); /* in func */
retries := retries - 1; /* in func */
end loop; /* in func */
end; /* in func */
$$ language plpgsql;
1: create table reader_waits_for_lock_table(a int, b int) distributed by (a);
1: insert into reader_waits_for_lock_table select 1, 1;
-- Aquire a conflicting lock in utility mode on seg0.
0U: BEGIN;
0U: LOCK reader_waits_for_lock_table IN ACCESS EXCLUSIVE MODE;
-- A utility mode connection should not have valid gp_session_id, else
-- locks aquired by it may not confict with locks requested by a
-- normal mode backend.
0U: show gp_session_id;
-- Run the same query involving at least one reader gang. It should
-- block this time.
1&: SELECT t1.* FROM reader_waits_for_lock_table t1 INNER JOIN reader_waits_for_lock_table t2 ON t1.b = t2.b;
-- At least one reader process from session 1 should be blocked on
-- AccessExclusiveLock held by 0U. That distinct is needed because
-- plans for above select query differ between Orca and planner.
-- Planner generates three slices such that the two reader backends
-- are blocked for the lock. Orca generates two slices such that the
-- reader and as well as the writer are blocked. We get two rows (due
-- to "mppwriter=false" predicate) with planner and one row with Orca.
0U: select check_readers_are_blocked();
0U: select distinct relation::regclass, mode, query
from pg_locks l join pg_stat_activity a on a.pid = l.pid
and a.query like '%reader_waits_for_lock_table%'
and not a.pid = pg_backend_pid()
and l.granted = false and l.mppiswriter = false;
0U: COMMIT;
1<: