关键字:
数据库、锁、阻塞、父进程、人大金仓、KingbaseES
锁存在的意义
数据库往往是支持多用户、高并发的场景;当多个会话同时访问数据库的同一数据时,理想状态是为所有会话提供高效的访问,并且还要保持数据的一致性。那么数据库是怎么保持一致性的呢?KingbaseES数据库就是通过MVCC+锁机制来实现这一功能的。
KingbaseES提供了多种锁模式用于控制对表中数据的并发访问,下文是对这些锁的详细介绍以及获取各类锁并造成阻塞的场景。
锁的获取以及阻塞
在KingbaseES中,锁大致分为8种,分别是:1)AccessShareLock、2)RowShareLock、3)RowExclusionLock、4)AccessExclusionLock、5)ShareUpdateExclusiveLock、6)ShareLock、7)ShareRowExclusiveLock、8)ExclusiveLock。
因为不同的锁之间的兼容性关系,在有些时刻,一个事务中的锁需要等待另一个事务中的锁释放它所占用的资源,这就是阻塞。阻塞并不是一件坏事,是为了确保事务可以并发正常的运行。
KingbaseES查询锁详情的sql语句:
select pd.datname as datname, sys_blocking_pids(pl.pid) as blocking_pid, pl.pid as pid, pl.mode, psa.query as query from (select distinct database, pid, mode from sys_locks) pl join sys_database pd on pl.database = pd.oid join sys_stat_activity psa on pl.pid = psa.pid
- AccessShareLock:是共享读锁,任何只读取表而不修改它的查询都将获得这种锁模式,此时不允许DDL。
1)开启Session1:对test表做查询操作;
2)查询当前锁详情:
3)开启session2:对test表做删除操作,造成阻塞场景:
4)再次查询锁详情:
可以发现进程号为8481的进程(即删除表的进程)被进程号为7647的进程(即查询进程)所阻塞。
- RowShareLock:select for update, select for share 情况下会出现此锁,此时不允许DML和DDL操作。
1)开启Session1:对test表做查询操作;
2)开启Session2:对表进行更新操作:
3)通过Kmonitor查询锁信息:
- RowExclusionLock:DML会产生此锁,此时不允许DML相同记录,也不允许DDL;
1)开启Session1,对表进行更新操作,获取该锁:
2)通过Kmonitor查询锁信息:
3)开启session2,对表进行更新操作,形成阻塞:
4)通过Kmonitor查询锁信息:
- AccessExclusionLock:create、ALTER TABLE、DROP TABLE、TRUNCATE、REINDEX、CLUSTER、VACUUM FULL和REFRESH MATERIALIZED VIEW表会产生此锁。这种模式保证持有者是访问该表的唯一事务。此锁会阻塞查询。
1)session1:
2)通过Kmonitor查询锁信息:
3)session2:
4)session3:
5)通过Kmonitor查询锁信息:
- ShareUpdateExclusiveLock:由Vacuum(不带FULL)、ANALYZE、CREATE INDEX CONCURRENTLY、CREATE STATISTICS和ALTER TABLE VALIDATE以及其他ALTER TABLE的变体获得此锁,这种模式保护一个表不受并发模式改变和VACUUM运行的影响
1)session1:
2)通过Kmonitor查询锁信息:
3)session2:
4)通过Kmonitor查询锁信息: - ShareLock:CREATE INDEX(WITHOUT CONCURRENTLY)会获得此锁,这种模式保护一个表不受并发数据改变的影响,即不能修改此表相关的数据和表结构。
1)session:
2)通过sql查询锁信息:
3)session2:
4)通过sql查询锁信息:
- ShareRowExclusiveLock:这种模式保护一个表不受并发数据修改锁影响,并且是自排他的,这样一个时刻只能又有一个会话持有它。由create trigger和某些形式的alter table所获得。
1)session1:
2)通过sql查询锁信息:
3)session2:
4)通过sql查询锁信息:
- 构造ExclusiveLock锁:该锁只允许并发的ACCESS SHARE锁,与其他锁都冲突,只有只读操作能在一个事务持有排他锁的时候进行并发操作。该锁不会被任何命令自动获取。
1)session1:
2)通过sql查询锁信息:
3)session2:
4)通过sql查询锁信息: