GaussDB(DWS) 锁管理介绍

举报
飞翔的罗杰 发表于 2020/12/23 17:42:14 2020/12/23
【摘要】 一,表锁GaussDB(DWS) 支持的表锁级别很多,从最低的1级到最高的8级:1级锁,AccessShareLockSELECT语句申请AccessShareLock,只与8级锁冲突,只会阻塞DDL等语句。2级锁,RowShareLockSELECT FOR SHARE/UPDATE语句申请RowShareLock,与7/8级锁冲突。3级锁,RowExclusiveLockINSERT/U...

一,表锁

GaussDB(DWS) 支持的表锁级别很多,从最低的1级到最高的8级:

lock1.jpg

1级锁,AccessShareLock

SELECT语句申请AccessShareLock,只与8级锁冲突,只会阻塞DDL等语句。

2级锁,RowShareLock

SELECT FOR SHARE/UPDATE语句申请RowShareLock,与7/8级锁冲突。

3级锁,RowExclusiveLock

INSERT/UPDATE/DELET语句申请RowExclusiveLock,与6-8级锁冲突。

4级锁,ShareUpdateExclusiveLock

VACUUM/ANALYZE语句申请ShareUpdateExclusiveLock,与5-8级锁冲突。

5级锁,ShareLock

CREATE INDEX语句申请ShareLock,与4/6/7/8级锁冲突,与5级锁不冲突,同一个表的多个CREATE INDEX可以同时执行不阻塞。

6级锁,ShareRowExclusiveLock

在GaussDB(DWS) 中,ShareRowExclusiveLock目前只在ALTER SEQUENCE中用到,阻塞表的增删改以及更高级别操作,该锁与3-8级锁冲突。

7级锁,ExclusiveLock

VACUUM FULL,MERGE PARTITION等语句申请ExclusiveLock级锁,ExclusiveLock只与SELECT兼容,与2-8级锁冲突。
除了表锁外,事务锁,扩展锁、记录锁都是使用的ExclusiveLock,下面会进行详细介绍。

8级锁,AccessExclusiveLock

DDL等语句会申请AccessExclusiveLock,包括ALTER TABLE,DROP TABLE,TRUNCATE,REINDEX,VACUUM FULL等,8级锁与所有锁都冲突。


锁冲突矩阵

详细的锁冲突矩阵图如下所示:
 lock2.jpg

LOCK [TABLE]

表锁还可以手动的使用SQL语句的方式进行强制上锁,SQL语句的格式如下所示:
LOCK [ TABLE ] [ ONLY ] name [ * ] [, ...] [ IN lockmode MODE ] [ NOWAIT ]

其中 lockmode 可以是以下之一:
    ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE
    | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE

要注意的是LOCK语句只能在事务块中执行,事务结束会释放

二,其他锁

除了表锁,GaussDB(DWS) 中还有很多其他的锁,下面列出一些常用的锁:

1,事务锁

写事务会获取一个事务号,并且会以这个事务号申请一个事务锁,锁级别是7级锁ExclusiveLock。
事务锁用于控制记录的并发修改,比如,两个事务先后修改同一条记录,在前一个事务未结束之前,后一个事务会等待在前一个事务的事务锁上。

2,记录锁

当出现并发更新冲突时,冲突的事务会申请记录锁,锁级别是7级锁ExclusiveLock。
记录锁主要是提高等待事务的优先级,在更新事务结束后,让持有记录锁的事务第一个被唤醒。

3,扩展锁

文件扩展时,会申请扩展锁,扩展锁的锁级别是7级锁ExclusiveLock。
表、索引、fsm、vm等文件扩展时都会申请扩展锁。

4,分区锁

分区锁是专门针对分区表的,分区锁的意义与表锁差不多,锁级别从1-8都有。

三,用户自定义锁

也叫advisory lock,用户可以通过调用GaussDB(DWS) 提供的函数来自定义锁,自定义锁按照作用范围分为两类:

1,事务级自定义锁

作用范围在本事务内部,可以手动调用函数释放,也可以事务结束自动释放。相关函数:
pg_advisory_xact_lock(key bigint)
pg_advisory_xact_lock(key1 int, key2 int)
pg_advisory_xact_lock_shared(key bigint)
pg_advisory_xact_lock_shared(key1 int, key2 int)
pg_try_advisory_xact_lock(key bigint)
pg_try_advisory_xact_lock(key1 int, key2 int)
pg_try_advisory_xact_lock_shared(key bigint)
pg_try_advisory_xact_lock_shared(key1 int, key2 int)

2,session级自定义锁

作用范围跨越事务,需要手动调用相关函数进行合理的释放,session退出时也会强制释放。相关函数:
pg_advisory_lock(key bigint)
pg_advisory_lock(key1 int, key2 int)
pg_advisory_lock_shared(key bigint)
pg_advisory_lock_shared(key1 int, key2 int)
pg_try_advisory_lock(key bigint)
pg_try_advisory_lock(key1 int, key2 int)
pg_try_advisory_lock_shared(key bigint)
pg_try_advisory_lock_shared(key1 int, key2 int)

其中:

带shared后缀的相关函数会申请5级锁ShareLock,不带shared后缀的会申请7级锁ExclusiveLock。

带try标识的相关函数表示尝试申请锁,如果申请不到,直接返回,不需锁等待

四,如何查看锁等待

通过查询pg_locks视图查看单个节点的锁持有和等待状态,pg_locks视图的结构如下图:

lock3.jpg

其中:
locktype列表示锁类型,包括表锁、事务锁、扩展锁、自定义锁等;
relation列表示表的oid,如果是表锁,relation列会显示表的oid
transactionid表示事务号,如果是事务锁,transactionid列会显示session的事务号
mode列表示锁级别,级别1-8级;
pid列表示session的线程号;
granted列表示是否持有锁,‘t’表示持有锁,‘f'表示等待锁;

简单示例

先创建一张表t1(a int, b int);
并插入一条记录(1,1)。

1,先后创建两个连接session1,session2,同时对这条记录进行更新,更新顺序如下:
 lock4.jpg

2,对于session1,查看pg_locks,如下图所示

lock5.jpg

session1持有的锁主要包括:

1)持有表t1的3级锁RowExclusiveLock,表t1的oid是16384
2)持有session1的事务锁,事务号是2415620,锁级别7级(ExclusiveLock)

3,对于session2,查看pg_locks,如下图所示 lock6.jpg

由于session1的更新未结束,session2需要等待,session2相关的锁主要包括:

1)持有表t1的3级锁RowExclusiveLock,表t1的oid是16384
2)持有session2的事务锁,事务号是2415630
3)持有记录(1,1)的记录锁
4)等待session1事务结束释放事务锁,granted为’f',申请session1的事务号对应的5级锁(ShareLock),与session1持有7级事务锁冲突,需要锁等待

五,锁相关参数

GaussDB(DWS) 中锁等待可以设置等待超时相关参数,一旦等锁的时间超过参数配置值会抛错。

锁等待超时有两个参数::
1) lockwait_timeout
当出现表锁冲突的时候生效,当等待表锁的时间超过配置的时间,抛错返回,默认20分钟。
2) update_lockwait_timeout
当出现记录锁冲突的时候生效,如果等待记录锁的时间超过update_lockwait_timeout,抛错返回,默认20分钟。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200