blob: 0caadff3922417372e72a6b2510af7539da7e1c4 [file] [log] [blame]
-- table to just store the master's data directory path on segment.
CREATE TABLE lockmodes_datadir(a int, dir text);
CREATE
INSERT INTO lockmodes_datadir select 1,datadir from gp_segment_configuration where role='p' and content=-1;
INSERT 1
-- ORCA would upgrade lock to ExclusiveLock
1: set optimizer = on;
SET
create or replace view show_locks_lockmodes as select locktype, mode, granted, relation::regclass from pg_locks where gp_segment_id = -1 and locktype = 'relation' and relation::regclass::text like 't_lockmods%';
CREATE
show gp_enable_global_deadlock_detector;
gp_enable_global_deadlock_detector
------------------------------------
off
(1 row)
-- 1. The firs part of test is with
-- gp_enable_global_deadlock_detector off
--
-- because local deadlock detector can already detect and handle deadlocks in
-- singlenode mode, locking is acted as if GDD is enabled to provide better
-- concurrency, so locks won't be elevated from RowExclusive to Exclusive,
-- thus the following results are different from cluster mode.
-- 1.1 test for heap tables
create table t_lockmods (c int);
CREATE
insert into t_lockmods select * from generate_series(1, 5);
INSERT 5
analyze t_lockmods;
ANALYZE
create table t_lockmods1 (c int);
CREATE
create table t_lockmods_rep(c int);
CREATE
-- See github issue: https://github.com/greenplum-db/gpdb/issues/9449
-- upsert may lock tuples on segment, so we should upgrade lock level
-- on QD if GDD is disabled.
create table t_lockmods_upsert(a int, b int) ;
CREATE
create unique index uidx_t_lockmodes_upsert on t_lockmods_upsert(a, b);
CREATE
-- add analyze to avoid auto vacuum when executing first insert
analyze t_lockmods_upsert;
ANALYZE
-- 1.1.1 select for (update|share|key share|no key update) should hold ExclusiveLock on range tables
1: begin;
BEGIN
1: explain select * from t_lockmods for update;
QUERY PLAN
-----------------------------------------------------------
Seq Scan on t_lockmods (cost=0.00..1.05 rows=5 width=10)
Optimizer: Postgres query optimizer
(2 rows)
1: select * from t_lockmods for update;
c
---
1
2
3
4
5
(5 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+------------
relation | AccessShareLock | t | t_lockmods
relation | ExclusiveLock | t | t_lockmods
(2 rows)
1: abort;
ABORT
1: begin;
BEGIN
1: explain select * from t_lockmods for no key update;
QUERY PLAN
-----------------------------------------------------------
Seq Scan on t_lockmods (cost=0.00..1.05 rows=5 width=10)
Optimizer: Postgres query optimizer
(2 rows)
1: select * from t_lockmods for no key update;
c
---
1
2
3
4
5
(5 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+------------
relation | AccessShareLock | t | t_lockmods
relation | ExclusiveLock | t | t_lockmods
(2 rows)
1: abort;
ABORT
1: begin;
BEGIN
1: explain select * from t_lockmods for share;
QUERY PLAN
-----------------------------------------------------------
Seq Scan on t_lockmods (cost=0.00..1.05 rows=5 width=10)
Optimizer: Postgres query optimizer
(2 rows)
1: select * from t_lockmods for share;
c
---
1
2
3
4
5
(5 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+------------
relation | AccessShareLock | t | t_lockmods
relation | ExclusiveLock | t | t_lockmods
(2 rows)
1: abort;
ABORT
1: begin;
BEGIN
1: explain select * from t_lockmods for key share;
QUERY PLAN
-----------------------------------------------------------
Seq Scan on t_lockmods (cost=0.00..1.05 rows=5 width=10)
Optimizer: Postgres query optimizer
(2 rows)
1: select * from t_lockmods for key share;
c
---
1
2
3
4
5
(5 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+------------
relation | AccessShareLock | t | t_lockmods
relation | ExclusiveLock | t | t_lockmods
(2 rows)
1: abort;
ABORT
1: begin;
BEGIN
1: explain select * from t_lockmods, t_lockmods1 for update;
QUERY PLAN
------------------------------------------------------------------------
Nested Loop (cost=10000000000.00..10000000752.74 rows=51150 width=20)
-> Seq Scan on t_lockmods1 (cost=0.00..112.30 rows=10230 width=10)
-> Materialize (cost=0.00..1.07 rows=5 width=10)
-> Seq Scan on t_lockmods (cost=0.00..1.05 rows=5 width=10)
Optimizer: Postgres query optimizer
(5 rows)
1: select * from t_lockmods, t_lockmods1 for update;
c | c
---+---
(0 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+-------------
relation | AccessShareLock | t | t_lockmods
relation | ExclusiveLock | t | t_lockmods
relation | AccessShareLock | t | t_lockmods1
relation | ExclusiveLock | t | t_lockmods1
(4 rows)
1: abort;
ABORT
1: begin;
BEGIN
1: explain select * from t_lockmods, t_lockmods1 for no key update;
QUERY PLAN
------------------------------------------------------------------------
Nested Loop (cost=10000000000.00..10000000752.74 rows=51150 width=20)
-> Seq Scan on t_lockmods1 (cost=0.00..112.30 rows=10230 width=10)
-> Materialize (cost=0.00..1.07 rows=5 width=10)
-> Seq Scan on t_lockmods (cost=0.00..1.05 rows=5 width=10)
Optimizer: Postgres query optimizer
(5 rows)
1: select * from t_lockmods, t_lockmods1 for no key update;
c | c
---+---
(0 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+-------------
relation | AccessShareLock | t | t_lockmods
relation | ExclusiveLock | t | t_lockmods
relation | AccessShareLock | t | t_lockmods1
relation | ExclusiveLock | t | t_lockmods1
(4 rows)
1: abort;
ABORT
1: begin;
BEGIN
1: explain select * from t_lockmods, t_lockmods1 for share;
QUERY PLAN
------------------------------------------------------------------------
Nested Loop (cost=10000000000.00..10000000752.74 rows=51150 width=20)
-> Seq Scan on t_lockmods1 (cost=0.00..112.30 rows=10230 width=10)
-> Materialize (cost=0.00..1.07 rows=5 width=10)
-> Seq Scan on t_lockmods (cost=0.00..1.05 rows=5 width=10)
Optimizer: Postgres query optimizer
(5 rows)
1: select * from t_lockmods, t_lockmods1 for share;
c | c
---+---
(0 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+-------------
relation | AccessShareLock | t | t_lockmods
relation | ExclusiveLock | t | t_lockmods
relation | AccessShareLock | t | t_lockmods1
relation | ExclusiveLock | t | t_lockmods1
(4 rows)
1: abort;
ABORT
1: begin;
BEGIN
1: explain select * from t_lockmods, t_lockmods1 for key share;
QUERY PLAN
------------------------------------------------------------------------
Nested Loop (cost=10000000000.00..10000000752.74 rows=51150 width=20)
-> Seq Scan on t_lockmods1 (cost=0.00..112.30 rows=10230 width=10)
-> Materialize (cost=0.00..1.07 rows=5 width=10)
-> Seq Scan on t_lockmods (cost=0.00..1.05 rows=5 width=10)
Optimizer: Postgres query optimizer
(5 rows)
1: select * from t_lockmods, t_lockmods1 for key share;
c | c
---+---
(0 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+-------------
relation | AccessShareLock | t | t_lockmods
relation | ExclusiveLock | t | t_lockmods
relation | AccessShareLock | t | t_lockmods1
relation | ExclusiveLock | t | t_lockmods1
(4 rows)
1: abort;
ABORT
-- 1.1.2 update | delete should hold ExclusiveLock on result relations
1: begin;
BEGIN
1: update t_lockmods set c = c + 0;
UPDATE 5
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+------------------+---------+------------
relation | RowExclusiveLock | t | t_lockmods
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: delete from t_lockmods;
DELETE 5
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+------------------+---------+------------
relation | RowExclusiveLock | t | t_lockmods
(1 row)
1: abort;
ABORT
-- 1.1.3 insert should hold RowExclusiveLock on result relations
1: begin;
BEGIN
1: insert into t_lockmods select * from generate_series(1, 5);
INSERT 5
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+------------------+---------+------------
relation | RowExclusiveLock | t | t_lockmods
(1 row)
1: abort;
ABORT
-- 1.1.4 upsert should hold ExclusiveLock on result relations
1: begin;
BEGIN
1: insert into t_lockmods_upsert values (1, 1) on conflict(a, b) do update set b = 99;
INSERT 1
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+------------------+---------+-------------------
relation | RowExclusiveLock | t | t_lockmods_upsert
(1 row)
1: abort;
ABORT
-- 1.1.5 use cached plan should be consistent with no cached plan
1: prepare select_for_update as select * from t_lockmods for update;
PREPARE
1: prepare select_for_nokeyupdate as select * from t_lockmods for no key update;
PREPARE
1: prepare select_for_share as select * from t_lockmods for share;
PREPARE
1: prepare select_for_keyshare as select * from t_lockmods for key share;
PREPARE
1: prepare update_tlockmods as update t_lockmods set c = c + 0;
PREPARE
1: prepare delete_tlockmods as delete from t_lockmods;
PREPARE
1: prepare insert_tlockmods as insert into t_lockmods select * from generate_series(1, 5);
PREPARE
1: prepare upsert_tlockmods as insert into t_lockmods_upsert values (1, 1) on conflict(a, b) do update set b = 99;
PREPARE
1: begin;
BEGIN
1: execute select_for_update;
c
---
1
2
3
4
5
(5 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+---------------+---------+------------
relation | ExclusiveLock | t | t_lockmods
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: execute select_for_nokeyupdate;
c
---
1
2
3
4
5
(5 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+---------------+---------+------------
relation | ExclusiveLock | t | t_lockmods
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: execute select_for_share;
c
---
1
2
3
4
5
(5 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+---------------+---------+------------
relation | ExclusiveLock | t | t_lockmods
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: execute select_for_keyshare;
c
---
1
2
3
4
5
(5 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+---------------+---------+------------
relation | ExclusiveLock | t | t_lockmods
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: execute update_tlockmods;
EXECUTE 5
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+------------------+---------+------------
relation | RowExclusiveLock | t | t_lockmods
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: execute delete_tlockmods;
EXECUTE 5
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+------------------+---------+------------
relation | RowExclusiveLock | t | t_lockmods
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: execute insert_tlockmods;
EXECUTE 5
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+------------------+---------+------------
relation | RowExclusiveLock | t | t_lockmods
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: execute upsert_tlockmods;
EXECUTE 1
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+------------------+---------+-------------------
relation | RowExclusiveLock | t | t_lockmods_upsert
(1 row)
1: abort;
ABORT
-- 1.2 test for AO table
create table t_lockmods_ao (c int) with (appendonly=true);
CREATE
insert into t_lockmods_ao select * from generate_series(1, 8);
INSERT 8
analyze t_lockmods_ao;
ANALYZE
create table t_lockmods_ao1 (c int) with (appendonly=true);
CREATE
-- 1.2.1 select for (update|share|key share|no key update) should hold ExclusiveLock on range tables
1: begin;
BEGIN
1: explain select * from t_lockmods_ao for update;
QUERY PLAN
--------------------------------------------------------------
Seq Scan on t_lockmods_ao (cost=0.00..1.08 rows=8 width=10)
Optimizer: Postgres query optimizer
(2 rows)
1: select * from t_lockmods_ao for update;
c
---
1
2
3
4
5
6
7
8
(8 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+---------------
relation | AccessShareLock | t | t_lockmods_ao
relation | ExclusiveLock | t | t_lockmods_ao
(2 rows)
1: abort;
ABORT
1: begin;
BEGIN
1: explain select * from t_lockmods_ao for no key update;
QUERY PLAN
--------------------------------------------------------------
Seq Scan on t_lockmods_ao (cost=0.00..1.08 rows=8 width=10)
Optimizer: Postgres query optimizer
(2 rows)
1: select * from t_lockmods_ao for no key update;
c
---
1
2
3
4
5
6
7
8
(8 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+---------------
relation | AccessShareLock | t | t_lockmods_ao
relation | ExclusiveLock | t | t_lockmods_ao
(2 rows)
1: abort;
ABORT
1: begin;
BEGIN
1: explain select * from t_lockmods_ao for share;
QUERY PLAN
--------------------------------------------------------------
Seq Scan on t_lockmods_ao (cost=0.00..1.08 rows=8 width=10)
Optimizer: Postgres query optimizer
(2 rows)
1: select * from t_lockmods_ao for share;
c
---
1
2
3
4
5
6
7
8
(8 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+---------------
relation | AccessShareLock | t | t_lockmods_ao
relation | ExclusiveLock | t | t_lockmods_ao
(2 rows)
1: abort;
ABORT
1: begin;
BEGIN
1: explain select * from t_lockmods_ao for key share;
QUERY PLAN
--------------------------------------------------------------
Seq Scan on t_lockmods_ao (cost=0.00..1.08 rows=8 width=10)
Optimizer: Postgres query optimizer
(2 rows)
1: select * from t_lockmods_ao for key share;
c
---
1
2
3
4
5
6
7
8
(8 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+---------------
relation | AccessShareLock | t | t_lockmods_ao
relation | ExclusiveLock | t | t_lockmods_ao
(2 rows)
1: abort;
ABORT
1: begin;
BEGIN
1: explain select * from t_lockmods_ao, t_lockmods_ao1 for update;
QUERY PLAN
---------------------------------------------------------------------
Nested Loop (cost=10000000000.00..10000000001.24 rows=8 width=20)
-> Seq Scan on t_lockmods_ao (cost=0.00..1.08 rows=8 width=10)
-> Seq Scan on t_lockmods_ao1 (cost=0.00..0.01 rows=1 width=10)
Optimizer: Postgres query optimizer
(4 rows)
1: select * from t_lockmods_ao, t_lockmods_ao1 for update;
c | c
---+---
(0 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+----------------
relation | AccessShareLock | t | t_lockmods_ao
relation | ExclusiveLock | t | t_lockmods_ao
relation | AccessShareLock | t | t_lockmods_ao1
relation | ExclusiveLock | t | t_lockmods_ao1
(4 rows)
1: abort;
ABORT
1: begin;
BEGIN
1: explain select * from t_lockmods_ao, t_lockmods_ao1 for no key update;
QUERY PLAN
---------------------------------------------------------------------
Nested Loop (cost=10000000000.00..10000000001.24 rows=8 width=20)
-> Seq Scan on t_lockmods_ao (cost=0.00..1.08 rows=8 width=10)
-> Seq Scan on t_lockmods_ao1 (cost=0.00..0.01 rows=1 width=10)
Optimizer: Postgres query optimizer
(4 rows)
1: select * from t_lockmods_ao, t_lockmods_ao1 for no key update;
c | c
---+---
(0 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+----------------
relation | AccessShareLock | t | t_lockmods_ao
relation | ExclusiveLock | t | t_lockmods_ao
relation | AccessShareLock | t | t_lockmods_ao1
relation | ExclusiveLock | t | t_lockmods_ao1
(4 rows)
1: abort;
ABORT
1: begin;
BEGIN
1: explain select * from t_lockmods_ao, t_lockmods_ao1 for share;
QUERY PLAN
---------------------------------------------------------------------
Nested Loop (cost=10000000000.00..10000000001.24 rows=8 width=20)
-> Seq Scan on t_lockmods_ao (cost=0.00..1.08 rows=8 width=10)
-> Seq Scan on t_lockmods_ao1 (cost=0.00..0.01 rows=1 width=10)
Optimizer: Postgres query optimizer
(4 rows)
1: select * from t_lockmods_ao, t_lockmods_ao1 for share;
c | c
---+---
(0 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+----------------
relation | AccessShareLock | t | t_lockmods_ao
relation | ExclusiveLock | t | t_lockmods_ao
relation | AccessShareLock | t | t_lockmods_ao1
relation | ExclusiveLock | t | t_lockmods_ao1
(4 rows)
1: abort;
ABORT
1: begin;
BEGIN
1: explain select * from t_lockmods_ao, t_lockmods_ao1 for key share;
QUERY PLAN
---------------------------------------------------------------------
Nested Loop (cost=10000000000.00..10000000001.24 rows=8 width=20)
-> Seq Scan on t_lockmods_ao (cost=0.00..1.08 rows=8 width=10)
-> Seq Scan on t_lockmods_ao1 (cost=0.00..0.01 rows=1 width=10)
Optimizer: Postgres query optimizer
(4 rows)
1: select * from t_lockmods_ao, t_lockmods_ao1 for key share;
c | c
---+---
(0 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+----------------
relation | AccessShareLock | t | t_lockmods_ao
relation | ExclusiveLock | t | t_lockmods_ao
relation | AccessShareLock | t | t_lockmods_ao1
relation | ExclusiveLock | t | t_lockmods_ao1
(4 rows)
1: abort;
ABORT
-- 1.2.2 update | delete should hold ExclusiveLock on result relations
1: begin;
BEGIN
1: update t_lockmods_ao set c = c + 0;
UPDATE 8
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+---------------+---------+---------------
relation | ExclusiveLock | t | t_lockmods_ao
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: delete from t_lockmods_ao;
DELETE 8
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+---------------+---------+---------------
relation | ExclusiveLock | t | t_lockmods_ao
(1 row)
1: abort;
ABORT
-- 1.2.3 insert should hold RowExclusiveLock on result relations
1: begin;
BEGIN
1: insert into t_lockmods_ao select * from generate_series(1, 5);
INSERT 5
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+------------------+---------+---------------
relation | RowExclusiveLock | t | t_lockmods_ao
(1 row)
1: abort;
ABORT
-- 1.2.4 use cached plan should be consistent with no cached plan
1: prepare select_for_update_ao as select * from t_lockmods_ao for update;
PREPARE
1: prepare select_for_nokeyupdate_ao as select * from t_lockmods_ao for no key update;
PREPARE
1: prepare select_for_share_ao as select * from t_lockmods_ao for share;
PREPARE
1: prepare select_for_keyshare_ao as select * from t_lockmods_ao for key share;
PREPARE
1: prepare update_tlockmods_ao as update t_lockmods_ao set c = c + 0;
PREPARE
1: prepare delete_tlockmods_ao as delete from t_lockmods_ao;
PREPARE
1: prepare insert_tlockmods_ao as insert into t_lockmods_ao select * from generate_series(1, 5);
PREPARE
1: begin;
BEGIN
1: execute select_for_update_ao;
c
---
1
2
3
4
5
6
7
8
(8 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+---------------+---------+---------------
relation | ExclusiveLock | t | t_lockmods_ao
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: execute select_for_nokeyupdate_ao;
c
---
1
2
3
4
5
6
7
8
(8 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+---------------+---------+---------------
relation | ExclusiveLock | t | t_lockmods_ao
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: execute select_for_share_ao;
c
---
1
2
3
4
5
6
7
8
(8 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+---------------+---------+---------------
relation | ExclusiveLock | t | t_lockmods_ao
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: execute select_for_keyshare_ao;
c
---
1
2
3
4
5
6
7
8
(8 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+---------------+---------+---------------
relation | ExclusiveLock | t | t_lockmods_ao
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: execute update_tlockmods_ao;
EXECUTE 8
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+---------------+---------+---------------
relation | ExclusiveLock | t | t_lockmods_ao
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: execute delete_tlockmods_ao;
EXECUTE 8
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+---------------+---------+---------------
relation | ExclusiveLock | t | t_lockmods_ao
(1 row)
1: abort;
ABORT
1: begin;
BEGIN
1: execute insert_tlockmods_ao;
EXECUTE 5
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+------------------+---------+---------------
relation | RowExclusiveLock | t | t_lockmods_ao
(1 row)
1: abort;
ABORT
-- 1.3 With limit clause, such case should
-- acquire ExclusiveLock on the whole table and do not generate lockrows node
1: begin;
BEGIN
1: explain select * from t_lockmods order by c limit 1 for update;
QUERY PLAN
-----------------------------------------------------------------------
Limit (cost=1.07..1.08 rows=1 width=10)
-> Sort (cost=1.07..1.09 rows=5 width=10)
Sort Key: c
-> Seq Scan on t_lockmods (cost=0.00..1.05 rows=5 width=10)
Optimizer: Postgres query optimizer
(5 rows)
1: select * from t_lockmods order by c limit 1 for update;
c
---
1
(1 row)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+------------
relation | AccessShareLock | t | t_lockmods
relation | ExclusiveLock | t | t_lockmods
(2 rows)
1: abort;
ABORT
-- 1.4 For replicated table, we should lock the entire table on ExclusiveLock
1: begin;
BEGIN
1: explain select * from t_lockmods_rep for update;
QUERY PLAN
---------------------------------------------------------------------
Seq Scan on t_lockmods_rep (cost=0.00..112.30 rows=10230 width=10)
Optimizer: Postgres query optimizer
(2 rows)
1: select * from t_lockmods_rep for update;
c
---
(0 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+----------------
relation | AccessShareLock | t | t_lockmods_rep
relation | ExclusiveLock | t | t_lockmods_rep
(2 rows)
1: abort;
ABORT
-- 1.5 test order-by's plan
1: begin;
BEGIN
1: explain select * from t_lockmods order by c for update;
QUERY PLAN
-----------------------------------------------------------------
Sort (cost=1.11..1.12 rows=5 width=10)
Sort Key: c
-> Seq Scan on t_lockmods (cost=0.00..1.05 rows=5 width=10)
Optimizer: Postgres query optimizer
(4 rows)
1: select * from t_lockmods order by c for update;
c
---
1
2
3
4
5
(5 rows)
2: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+-----------------+---------+------------
relation | AccessShareLock | t | t_lockmods
relation | ExclusiveLock | t | t_lockmods
(2 rows)
1: abort;
ABORT
-- 1.6 select for update NOWAIT/SKIP LOCKED
-- NOWAIT/SKIP LOCKED should not affect the table-level lock
1: begin;
BEGIN
1: select * from t_lockmods for share;
c
---
1
2
3
4
5
(5 rows)
2&: select * from t_lockmods for update nowait; <waiting ...>
1: abort;
ABORT
2<: <... completed>
c
---
1
2
3
4
5
(5 rows)
1: begin;
BEGIN
1: select * from t_lockmods for share;
c
---
1
2
3
4
5
(5 rows)
2&: select * from t_lockmods for update skip locked; <waiting ...>
1: abort;
ABORT
2<: <... completed>
c
---
1
2
3
4
5
(5 rows)
1q: ... <quitting>
2q: ... <quitting>
-- 1.8 Test on DML lock behavior on Partition tables on QDs.
-- This suite will test:
-- * DML on root
-- * DML on one specific leaf
-- For detailed behavior and notes, please refer below
-- cases's comments.
-- Details: https://groups.google.com/a/greenplum.org/g/gpdb-dev/c/wAPKpJzhbpM
-- start_ignore
1:DROP TABLE IF EXISTS t_lockmods_part_tbl_upd_del;
DROP
-- end_ignore
1:CREATE TABLE t_lockmods_part_tbl_upd_del (a int, b int, c int) PARTITION BY RANGE(b) (START(1) END(3) EVERY(1));
CREATE
1:INSERT INTO t_lockmods_part_tbl_upd_del SELECT i, 1, i FROM generate_series(1,10)i;
INSERT 10
--
1: BEGIN;
BEGIN
1: DELETE FROM t_lockmods_part_tbl_upd_del;
DELETE 10
-- on QD, there's a lock on the root and the target partition
1: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+------------------+---------+-------------------------------------
relation | RowExclusiveLock | t | t_lockmods_part_tbl_upd_del_1_prt_2
relation | RowExclusiveLock | t | t_lockmods_part_tbl_upd_del_1_prt_1
relation | RowExclusiveLock | t | t_lockmods_part_tbl_upd_del
(3 rows)
1: ROLLBACK;
ROLLBACK
--
-- The session cannot be reused.
--
-- The macro RELCACHE_FORCE_RELEASE is defined iff USE_ASSERT_CHECKING is
-- defined, and when RELCACHE_FORCE_RELEASE is defined the relcache is
-- forcefully released when closing the relation.
--
-- The function generate_partition_qual() will behave differently depends on
-- the existence of the relcache.
--
-- - if the relation is not cached, it will open it in AccessShareLock mode,
-- and save the relpartbound in the relcache;
-- - if the relation is already cached, it will load the relpartbound from the
-- cache directly without opening the relation;
--
-- So as a result, in the following transactions we will see an extra
-- AccessShareLock lock in a --enable-cassert build compared to a
-- --disable-cassert build.
--
-- To make the test results stable, we do not reuse the sessions in the test,
-- all the tests are performed without the relcache.
1q: ... <quitting>
1: BEGIN;
BEGIN
1: UPDATE t_lockmods_part_tbl_upd_del SET c = 1 WHERE c = 1;
UPDATE 1
-- on QD, there's a lock on the root and the target partition
1: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+------------------+---------+-------------------------------------
relation | RowExclusiveLock | t | t_lockmods_part_tbl_upd_del_1_prt_2
relation | RowExclusiveLock | t | t_lockmods_part_tbl_upd_del_1_prt_1
relation | AccessShareLock | t | t_lockmods_part_tbl_upd_del
relation | RowExclusiveLock | t | t_lockmods_part_tbl_upd_del
(4 rows)
1: ROLLBACK;
ROLLBACK
1q: ... <quitting>
1: BEGIN;
BEGIN
1: DELETE FROM t_lockmods_part_tbl_upd_del_1_prt_1;
DELETE 10
-- since the delete operation is on leaf part, there will be a lock on QD
1: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+------------------+---------+-------------------------------------
relation | RowExclusiveLock | t | t_lockmods_part_tbl_upd_del_1_prt_1
(1 row)
1: ROLLBACK;
ROLLBACK
1q: ... <quitting>
1: BEGIN;
BEGIN
1: UPDATE t_lockmods_part_tbl_upd_del_1_prt_1 SET c = 1 WHERE c = 1;
UPDATE 1
-- since the update operation is on leaf part, there will be a lock on QD
1: select * from show_locks_lockmodes;
locktype | mode | granted | relation
----------+------------------+---------+-------------------------------------
relation | AccessShareLock | t | t_lockmods_part_tbl_upd_del
relation | RowExclusiveLock | t | t_lockmods_part_tbl_upd_del_1_prt_1
(2 rows)
1: ROLLBACK;
ROLLBACK
1q: ... <quitting>
TRUNCATE t_lockmods_ao;
TRUNCATE