解析OceanBase v4.2 Oracle 语法兼容之 LOCK TABLE

背景

OceanBase V4.1及之前的版本中,尽管已经为Oracle租户兼容了LOCK TABLE相关的语法,包括单表锁定操作,和WAIT N, NOWAIT 关键字。但使用时还存在一些限制。例如:LOCK TABLE只能针对单表进行锁定,并不支持多表或分区锁定;WAIT NNOWAIT 关键字在实际执行中并未发挥预期作用,即用户在语句中指定WAIT NNOWAIT后,实际的执行行为和关键字效果不一致,系统仍然会按照设定的语句超时时间和事务超时时间的最小值来等待锁,这意味着锁定操作可能会持续至语句超时或事务超时。

想要了解相关语法和描述可以参考官方文档。LOCK TABLE

在 Oceanbase 4.2 及之后的版本中,提供了更完备的 LOCK TABLE 语法兼容性,并补全了未生效的功能,包括对多表、多分区、多二级分区上锁,以及使WAIT NNOWAIT关键字生效。

LOCK TABLE 语法解析

LOCK TABLE 的语法如下所示:

LOCK TABLE
{
[ schema. ]  table
[ PARTITION '('partition ...')' 
 | SUBPARTITION '(' subpartition ...')' ] 
...
}
IN lockmode MODE
[ NOWAIT | WAIT integer] ;

其对应的语法结构图如下。

**lock_table::=**对应的语法结构见下图:

**partition_extension_clause::=**对应的语法结构见下图:

如果你对上述语法结构中的字段存疑,可以参考下表中对于LOCK TABLE 各字段的说明。

|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 字段名称 | 描述 |
| table | 指定要锁定的表的名称。 |
| partition | 指定要锁定的分区的名称。 |
| subpartition | 指定要锁定的二级分区的名称。 |
| lockmode | 指定锁定模式。OceanBase 数据库当前版本支持的锁定模式如下。ROW SHARE:允许并发访问锁定的表,但禁止用户锁定整个表而进行独占访问。ROW EXCLUSIVE :与 ROW SHARE 相同,但也禁止在 SHARE 模式下锁定表。在进行更新、插入或删除时,将自动获得 ROW EXCLUSIVE 锁。SHARE:允许并发查询,但禁止更新锁定的表。SHARE ROW EXCLUSIVE:用于查看整个表,并允许其他人查看表中的行,但禁止其他人在 SHARE 模式下锁定表或更新行。EXCLUSIVE:只允许对锁定的表进行查询,禁止对其进行其他操作。 |
| NOWAIT | 如果对执行的表、分区或二级分区上锁时发生锁冲突,则指定 NOWAIT 可以让数据库立即将控制权返回给用户。在这种情况下,数据库会返回一条消息,以告知表、分区或子分区已被另一个用户锁定。 |
| WAIT | 如果发生锁冲突,那么语句应该等待冲突的锁释放,直到超过用户设置的 interger 时间(单位对应为秒),integer 的值没有限制。 |

LOCK TABLE 语法实践

了解基本概念和原理后,我们来上手实践一下。以如下所示的表结构作为实践操作表,演示10个操作场景。其中,subpartition template 生成的二级分区名称为一级分区名称 + 's' + 二级分区模板名称,例如,p0分区有二级分区p0ssp0p0ssp1p0ssp2

create table test(col1 int, col2 int)
partition by range (col1)
subpartition by range (col2)
subpartition template
(
subpartition sp0 values less than (3),
subpartition sp1 values less than (6),
subpartition sp2 values less than (9)
)
(
partition p0 values less than (100),
partition p1 values less than (200),
partition p2 values less than (300)
);

场景1:对整个表上互斥锁。

lock table test in exclusive mode;

场景2:对一级分区 p1****上互斥锁。

lock table test partition (p1) in exclusive mode;

场景3:对二级分区 p1ssp1****上互斥锁。

lock table test subpartition (p1ssp1) in exclusive mode;

场景4:在两个客户端上分别对同一个表上锁,其中持锁客户端上互斥锁,请求锁客户端上共享锁。

# conn1
start transaction;
lock table test in exclusive mode;

# conn2
start transaction;
set ob_trx_timeout = 10000000000; # 10000 second
set ob_query_timeout = 1000000;   # 1 second

# client will get error code after 1 second
lock table test in share mode;
ERROR HY000: resource busy and acquire with NOWAIT specified or timeout expired

当 LOCK TABLE 语句不设置WAIT N/NOWAIT关键字时,其超时时间将取决于语句超时时间和事务超时时间的最小值,在该例子中即为 1 秒后将报出锁冲突错误。

场景5:在两个客户端上分别对同一个表上表锁,其中持锁客户端上互斥锁,请求锁客户端上共享锁,并使用 NOWAIT****关键字。

# conn1
start transaction;
lock table test in exclusive mode;

# conn2
start transaction;
lock table test in share mode nowait;
ERROR HY000: resource busy and acquire with NOWAIT specified or timeout expired

当 LOCK TABLE 语句设置了NOWAIT关键字后,若遇到表锁冲突将会立即报错,并在报错信息中体现"NOWAIT"信息。该报错信息与语句不设置WAIT N/NOWAIT关键字不同。

场景6:在两个客户端上分别对同一个表上表锁,其中持锁客户端上互斥锁,请求锁客户端上共享锁,并使用 WAIT N****关键字。

# conn1
start transaction;
lock table test in exclusive mode;

# conn2
start transaction;

# client will get error code after 1 second
lock table test in share mode wait 1;
ERROR HY000: resource busy and acquire with NOWAIT specified or timeout expired

当 LOCK TABLE 语句设置了WAIT N关键字后,若遇到表锁冲突将会等待N秒,若N秒后为解锁将报错,并在报错信息中体现"timeout expired"信息。该报错信息与语句不设置WAIT N/NOWAIT关键字不同。

场景7:对一个表的多个分区上互斥锁。

lock table test partition (p1,p2) in exclusive mode;

场景8:对一个表的多个二级分区上互斥锁。

lock table test subpartition (p0ssp1,p1ssp2) in exclusive mode;

场景9:对一个表的多个分区和二级分区上互斥锁。

lock table test partition (p1, p2), test subpartition (p3ssp0, p3ssp1) in exclusive mode;

场景10:对不存在的分区上互斥锁(其中 p3****分区不存在,但是 p0****分区也不会上锁成功,整条语句将回滚).

lock table test partition (p0, p3) in exclusive mode;
ERROR HY000: Specified partition does not exist

写在最后

LOCK TABLE 语句是生产场景中常用的并发控制手段,可以帮助用户简单高效地实现表级的 ddl / dml 互斥。本文介绍了 OceanBase v4.2 新增的 LOCK TABLE Oracle 语法兼容的新特性,从语法的结构、字段的描述等角度详细解析了该新特性的使用方法,并分享了新特性的场景实践,希望能够帮助大家更"丝滑"地使用该特性,也欢迎大家在评论区分享优化建议、使用体验等。

相关推荐
OceanBase数据库官方博客8 小时前
在OceanBase 中,实现自增列的4种方法
oceanbase·分布式数据库·运维管理
OceanBase数据库官方博客2 天前
OceanBase中,如何解读 obdiag 收集的火焰图 【DBA早下班系列】
oceanbase·分布式数据库·运维管理
OceanBase数据库官方博客7 天前
从1000s到10s,OceanBase 标量子查询的SQL优化实践
oceanbase·分布式数据库·sql优化
OceanBase数据库官方博客7 天前
客如云:大型业务报表的分区化改造提升性能|OceanBase 应用实践
数据分析·oceanbase·分布式数据库·实践经验
大数据在线7 天前
乘云而上,OceanBase再越山峰
阿里云·oceanbase·分布式数据库·aws·云数据库
OceanBase数据库官方博客10 天前
阳振坤:云时代数据库的思考 | OceanBase发布会实录
oceanbase·分布式数据库·年度发布会
RestCloud10 天前
OceanBase数据库结合ETLCloud快速实现数据集成
数据库·oceanbase·etl·分布式存储·数据集成·数据传输
OceanBase数据库官方博客10 天前
云+AI 时代的 OceanBase
oceanbase·分布式数据库·1024程序员节·年度发布会
筱筱打工人10 天前
DBerver 连接oceanBase 配置
oceanbase
不叫猫先生10 天前
【OceanBase探会】云与 AI 赋能一体化数据库的创新之旅
数据库·ai·oceanbase·1024程序员节