封锁粒度
也称作锁对象或者锁范围,表示封锁的作用范围。例如,一条记录上的锁只作用于该记录,一个关系上的锁作用于该关系中的所有记录。
可见,不同封锁粒度涉及封锁[lockdown]的数据量是不同的。
封锁对象的级别越高,涉及的数据量越大。封锁力度越大,如对整个数据库进行封锁,则将会对数据库中全部关系、记录进行封锁,系统处理单个事务的能力要强一些,系统开销相对小一些,但是,系统的并发度就会减小,处理并发事务的能力就会减弱。
反之,封锁粒度越小,如对单个表或记录进行封锁,系统的并发度就会高一些,系统开销也就会越大。
GBASE 8s的锁机制可以锁定不同的粒度对象,在一个系统中同时存在不同大小的封锁单元供不同的事务选择使用是比较理想的。
综合来说,锁对象粒度越高并发性越低,比如独占锁锁定数据库,这种情况他用户不能连接到该数据库。而如果仅独占一个表的某一行记录,那么他用户可以并行访问(读取、修改)其他记录。
所以,在系统要求多用户高并发访问的情况下,应当尽量采用低粒度的锁,比如采用行级锁。
如果系统要求较少并发,或者进行一些管理事务(数据库重建、表重建),则为了获得较高的性能,可以采用高粒度的锁。
如何设置锁
数据库级锁(Database level Locks)
CONNECT DATABASE
CREATE DATABASE
在我们通过CONNECT DATABASE或者CREATE DATABASE语句访问数据库时,系统都将自动在该数据库上加一个共享(S)锁,这样可以防止其他用户删除数据库或者在该数据库上加排它(X)锁。
表级锁(Table level Locks)
表级锁就是指锁定的对象是一个表,可以通过如下语句显式的对表加锁和释放锁:
Begin work;
Lock table tab1 exclusive mode;
Lock table tab2 in share mode;
Unlock table tab1;
在执行一些DDL语句时,GBASE 8s 会自动对表进行加锁,如:
alter fragment
alter index
alter table
create index(如果没有使用online模式)
drop index(如果没有使用online模式)
rename column
rename table
通常而言,在整个表或者表中的大部分数据需要更新时,使用表级锁的效率高。
页级锁(page locks)
GBASE 8s会在物理上把多行记录存放在数据页(page)上,页级锁的对象是一个数据页,当采用页级锁访问记录时,GBASE 8s会自动对访问的数据页进行加锁。当按物理顺序访问和更新更多条记录时,使用页级锁的效率较高。
可以通过如下方式指定页级锁模式:
Alter table tab1 lock mode(page);
Create table tab1 (…) lockmode page;
Create table 时若不指定锁模式,则将采用onconfig中参数 def_table_lockmode来指定表的锁模式。
行级锁(row locks)
关系型数据库的数据是按行来管理的,所以行级锁很容易理解。在OLTP系统中行级锁的使用范围广泛。只需要锁定所访问的少数记录情况,使用行级锁的效率较高。
可以通过如下方式指定行级锁模式:
Alter table tab1 lock mode (row);
Create table tab1 (…) lock mode row;
Create table时若不指定锁模式,则将采用onconfig参数DEF_TABLE_LOCKMODE来指定表的锁模式。
索引锁(index locks)
索引采用B+树的存储结构,所以对索引的锁管理就是管理索引的key值,数据库采用开、闭区域的方式进行索引的锁管理,示例如下:
Create table tab1 (c1 int,c2 int) lock mode row;
Create unique index idx_tab1 on tab1 (c1);
Insert into tab1 values(1,2);
Insert into tab1 values(2,2);
Insert into tab1 values(3,2);
假设表中只有如上3行记录,当执行update tab1 set c1 >= 3语句时,GBASE 8s 将对索引key值为3的记录进行闭合区间加锁,意味着此时不能新增key值大于3的记录。若此时执行insert into tab1 values(4,2),则会提示index锁冲突错误。