本文分享自华为云社区《GaussDB数据库SQL系列-LOCK TABLE》,作者:酷哥。
一、前言
GaussDB是一款高性能、高可用的分布式数据库,广泛应用于各类行业和场景。在GaussDB中,锁是实现并发控制的关键机制之一,用于协调多个事务之间的数据访问,确保数据的一致性和完整性。本文将围绕GaussDB数据库的LOCK TABLE 做一简单介绍。
二、GaussDB数据库的锁
GaussDB提供了多种锁模式用于控制对表中数据的并发访问。这些模式可以用在MVCC(多版本并发控制)无法给出期望行为的场合。同样,大多数GaussDB命令自动施加恰当的锁,以保证被引用的表在命令的执行过程中不会以一种不兼容的方式被删除或者修改。比如,在存在其他并发操作的时候,ALTER TABLE是不能在同一个表上执行的。
1、GaussDB中的LOCK TABLE
LOCK TABLE获取表级锁。
如果需要保持数据库数据的一致性,可以使用LOCK TABLE来阻止其他用户修改表。例如,一个应用需要保证表中的数据在事务的运行过程中不被修改。为实现这个目的,则可以对表进行锁定,这样将防止数据不被并发修改。LOCK TABLE只在一个事务块的内部有用,在事务结束时就会被释放。
1)语法格式
LOCK [ TABLE ] name IN {ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE} MODE
2)参数说明
1)name:要锁定的表的名称。
2)锁的模式:
- ACCESS SHARE:只读取表而不修改。所有对表进行读取而不修改的SQL语句都会自动请求这种锁。
- ROW SHARE:允许对表进行并发读取,禁止对表进行其他操作。SELECT FOR UPDATE和SELECT FOR SHARE命令会自动在目标表上请求ROW SHARE锁(且所有被引用但不是FOR SHARE/FOR UPDATE的其他表上,还会自动加上ACCESS SHARE锁)。对于分区表,SELECT FOR SHARE操作还会在DN上获取partition对象的ROW EXCLUSIVE锁进行并发控制。
- ROW EXCLUSIVE:与ROW SHARE锁相同,ROW EXCLUSIVE允许并发读取表,但是禁止修改表中数据。UPDATE,DELETE,INSERT命令会自动在目标表上请求这个锁(且所有被引用的其他表上还会自动加上的ACCESS SHARE锁)。通常情况下,所有会修改表数据的命令都会请求表的ROW EXCLUSIVE锁。
- SHARE UPDATE EXCLUSIVE:保护一个表的模式不被并发修改,以及禁止在目标表上执行垃圾回收命令(VACUUM)。VACUUM(不带FULL选项)、ANALYZE、CREATE INDEX CONCURRENTLY命令会自动请求这样的锁。
- SHARE:允许并发的查询,但是禁止对表进行修改。CREATE INDEX(不带CONCURRENTLY)语句会自动请求这种锁。
- EXCLUSIVE:允许对目标表进行并发查询,但是禁止任何其他操作。这个模式只允许并发加ACCESS SHARE锁,也就是说,只有对表的读动作可以和持有这个锁模式的事务并发执行。任何SQL语句都不会在用户表上自动请求这个锁模式。然而在某些操作的时候,会在某些系统表上请求它。
- SHARE ROW EXCLUSIVE:禁止对表进行任何的并发修改,而且是独占锁,因此一个会话中只能获取一次。任何SQL语句都不会自动请求这个锁模式。
- ACCESS EXCLUSIVE:保证其所有者(事务)是可以访问该表的唯一事务。ALTER TABLE,DROP TABLE,TRUNCATE,REINDEX,CLUSTER,VACUUM FULL命令会自动请求这种锁。在LOCK TABLE命令没有明确声明需要的锁模式时,它是缺省锁模式。
2、示例一:ACCESS EXCLUSIVE 模式
--创建测试表 DROP TABLE IF EXISTS omm2.company; CREATE TABLE omm2.company( id int4 PRIMARY key NOT NULL ,name varchar(10) NOT NULL ,age int4 NOT NULL ,address varchar(20) NOT NULL ,salary float4 NOT NULL ); --初始化数据 INSERT INTO omm2.company VALUES (1, 'Paul', 32, 'California', 20000); INSERT INTO omm2.company VALUES (2, 'Allen', 25, 'Texas', 15000); INSERT INTO omm2.company VALUES (3, 'Teddy', 23, 'Norway', 20000); INSERT INTO omm2.company VALUES (4, 'ZhangSan', 30, 'BeiJing', 30000); --启动一个事务 START TRANSACTION; LOCK TABLE omm2.company IN ACCESS EXCLUSIVE MODE; DELETE FROM omm2.company WHERE name ='Allen'; COMMIT;
解析:
- “START TRANSACTION;”:启动一个新的事务。在数据库中,事务是一组一起执行的SQL语句,要么全部成功,要么全部失败。这确保了数据的一致性。
- “LOCK TABLE omm2.company IN ACCESS EXCLUSIVE MODE;”:对omm2.company表进行了排他性锁定。在此模式下,其他会话不能对表进行读写操作,直到这个事务结束。这样可以防止在删除操作过程中其他事务对表产生干扰。
- “DELETE FROM omm2.company WHERE name =’Allen’; ”:从omm2.company表中删除了所有名为’Allen’的记录。
- “COMMIT;”:这行代码提交了前面的事务。在事务中执行的任何更改(在本例中是删除操作)在提交后才会永久保存在数据库中。
总的来说,这段代码删除了名为’Allen’的所有记录,并确保这个操作在提交之前不会被其他事务干扰。
3、示例二:SHARE ROW EXCLUSIVE 模式
--复用示例一的测试表 CREATE TABLE omm2.company1 AS TABLE omm2.company; --启动一个事务 START TRANSACTION; LOCK TABLE omm2.company1 IN SHARE ROW EXCLUSIVE MODE; DELETE FROM omm2.company1 WHERE name ='Allen'; COMMIT;
解析:
- “CREATE TABLE omm2.company1 AS TABLE omm2.company;”:创建了一个新的表omm2.company1,其结构复制自已有的表omm2.company。这种操作通常用于创建表的副本,或者为某个操作创建一个临时的、与原表结构相同的新表。
- “START TRANSACTION; ”:启动一个新的事务。在数据库中,事务是一组一起执行的SQL语句,要么全部成功,要么全部失败,这可以确保数据的一致性。
- “LOCK TABLE omm2.company1 IN SHARE ROW EXCLUSIVE MODE; ”:对表omm2.company1进行了排他性锁定。在这种模式下,其他会话不能对表进行读写操作,直到这个事务结束,这样可以防止在删除操作过程中其他事务对表产生干扰。
- “DELETE FROM omm2.company1 WHERE name =’Allen’;”:从表omm1.company1中删除了所有名为’Allen’的记录。
- “COMMIT;”:提交前面的事务。在事务中执行的任何更改(在本例中是删除操作)在提交后才会永久保存在数据库中。
三、小结
GaussDB数据库的锁机制是其重要的组成部分,用于支持并发控制和事务隔离。GaussDB实现了不同级别的事务隔离和并发控制,满足了不同场景下的需求。当然了,使用GaussDB数据库时也需要注意一些问题,如锁的管理和数据库的规划等。合理的锁管理和数据库规划能够提高系统的性能和可用性,反之则可能导致数据一致性问题或者系统故障。
点击关注,第一时间了解华为云新鲜技术~