备注: 上图是pg 表级锁的各种冲突模式对照表,‘X’表示冲突项, 在章节四中会对其中典型的锁模式进行模似演示。
四、实验
在这一章节中将会对图一中比较典型的锁冲突进行模似演练,了解这些在Postgresql DBA的日常维护工作中很有帮助,同时也能减少人为故障的发生。
4.1 Access exclusive 锁与Access share锁冲突
在日常维护中,大家应该执行过’ALTER
TABLE’更改表结构的DDL,例如加字段,更改字段数据类型等,根据章节二的理论,在执行’ALTER TABLE’命令时将申请一个Access
exclusive锁, 根据图一,大家知道Access exclusive
锁和所有的锁模式都冲突,那么,它将会’Select’命令冲突,因为Select 加的是Access
share锁,那么真的会与‘SELECT‘命令冲突吗,接下来给大家演示下:
--创建一张测试表 test_2 并插入测试数据
mydb=> create table test_2 (id integer,name varchar(32));
CREATE TABLE
mydb=> insert into test_2 values (1,'franc');
INSERT 0 1
mydb=> insert into test_2 values (2,'tan');
INSERT 0 1
mydb=> select * from test_2;
id | name
----+-------
1 | franc
2 | tan
(2 rows)
--会话一 查询表数据 ( 这里获得Access Shared 锁)
mydb=> begin;
BEGIN
mydb=> select * from test_2 where id=1;
id | name
----+-------
1 | franc
(1 row)
注意:这里begin开始事务,没有提交;
--会话二 更改表结构 (这里申请 Access Exclusive锁 )
mydb=> alter table test_2 add column sex char(1);
发现,命令一直等侍,执行不下去;
--会话三 查询状态
mydb=# select oid,relname from pg_class where relname='test_2';
oid | relname
-------+---------
33802 | test_2
mydb=# select locktype,database,relation,pid,mode from pg_locks where relation='33802';
locktype | database | relation | pid | mode
----------+----------+----------+-------+---------------------
relation | 16466 | 33802 | 18577 | AccessShareLock
relation | 16466 | 33802 | 18654 | AccessExclusiveLock
mydb=# select datname,procpid