【数据库】封锁机制,自旋锁、轻量级锁和常规锁


前言

目前多数数据库的并发控制采用的是两阶段锁(Two-Phase Locking,2PL)协议,2PL保证了并发事务执行的可串行化。
在多用户环境中,数据库使用多版本并发控制(Multiversion Concurrency Control,MVCC)和多种锁相结合来维护数据一致性。
事务锁竞争是数据库性能瓶颈常见问题


一、封锁机制

数据库自动使用不同类型的封锁来控制对数据的并发存取,防止用户之间的干扰。

1. 自旋锁(spinlock)

  • 通过不停的循环检查锁的状态来获得封锁的机制
  • 不支持死锁检测
  • 自旋锁在锁等待期间会占用CPU
  • 场景:一般用于并发的修改全局变量时使用

2. 轻量级锁(LWLock)

  • 轻量锁通常使用自旋锁实现
  • 支持读锁(LW_SHARED)和写锁(LW_EXCLUSIVE)
  • 读锁和读锁不冲突,读锁和写锁、写锁和写锁冲突
  • 不需要支持死锁检测
  • 场景:一般用于内存结构的封锁,在一些数据库中,统计信息以及扩展功能的相关数据会放在共享内存中。如对大量临时表进行create和truncated会出现消息失效,产生大量SInvalWriteLock锁,可以考虑对执行计划进行缓存或将临时表的封锁消息不进行发送处理。

3. 常规锁(Lock)

  • 常规是数据库特有的锁机制,主要保护sql可见的对象
  • 提供了多种封锁模式,支持自动死锁检测
  • 封锁对象:数据库对象(表、事务)
  • 封锁时间(2PL):对象打开时加锁,事务结束放锁
锁编号常规锁类型操作与之冲突的模式
1AccessShareLockselect8
2RowShareLockselect for update/share7,8
3RowExclusiveLockinsert/update/delete5,6,7,8
4ShareUpdateExclusiveLockvacuum4,5,6,7,8
5ShareLockcreate index3,4,6,7,8
6ShareRowExclusiveLock内部使用3,4,5,6,7,8
7ExclusiveLock内部使用,例如分配空间、事务锁等2,3,4,5,6,7,8
8AccessExclusiveLockdrop table/truncate/alter table/reindex/cluster全部

二、封锁对象类型

封锁类型一般包含了表、事务和其它类型。表包括系统表、用户表、索引,事务锁实现了通常意义行级锁的概念。
死锁:指两个或两个以上的进程(线程)在执行过程中,因争夺资源而造成的一种互相等待的现象。

对象类型等待事件名称说明
表级锁relation等待获得一个关系上的锁
事务锁transactionid等待一个事务结束
事务锁virtualxid等待获得一个虚拟xid锁
其它锁extend等待扩展一个关系,关系分配空间
其它锁page等待获得一个关系上的页面的锁 ,只有hash索引使用
其它锁tuple等待获得一个元组上的锁,select for update/share
其它锁object,userlock,advisory等待获得一个用户锁 ,文件、大对象等

三、封锁查询

封锁系统视图定义

test=# \d sys_locks
               视图 "sys_catalog.sys_locks"
        栏位        |   类型   | 校对规则 | 可空的 | 预设
--------------------+----------+----------+--------+------
 locktype           | text     |          |        |
 database           | oid      |          |        |
 relation           | oid      |          |        |
 page               | integer  |          |        |
 tuple              | smallint |          |        |
 virtualxid         | text     |          |        |
 transactionid      | xid      |          |        |
 classid            | oid      |          |        |
 objid              | oid      |          |        |
 objsubid           | smallint |          |        |
 virtualtransaction | text     |          |        |
 pid                | integer  |          |        |
 mode               | text     |          |        |
 granted            | boolean  |          |        |
 fastpath           | boolean  |          |        |
test=#

封锁查询

test=# select locktype,virtualxid,transactionid,pid,mode,granted from sys_locks order by pid;
  locktype  | virtualxid | transactionid |  pid  |      mode       | granted
------------+------------+---------------+-------+-----------------+---------
 relation   |            |               | 18796 | AccessShareLock | t
 relation   |            |               | 18796 | AccessShareLock | t
 virtualxid | 4/24       |               | 18796 | ExclusiveLock   | t
(3 行记录)
test=# select locktype,transactionid,mode,granted,count(*) from sys_locks group by locktype,transactionid,mode,granted;
  locktype  | transactionid |      mode       | granted | count
------------+---------------+-----------------+---------+-------
 relation   |               | AccessShareLock | t       |     2
 virtualxid |               | ExclusiveLock   | t       |     1
(2 行记录)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值