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

背景

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

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

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

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分区有二级分区p0ssp0、p0ssp1和p0ssp2。

复制代码
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 语法兼容的新特性,从语法的结构、字段的描述等角度详细解析了该新特性的使用方法,并分享了新特性的场景实践,希望能够帮助大家更"丝滑"地使用该特性,也欢迎大家在评论区分享优化建议、使用体验等。

相关推荐
运维小斌3 天前
麒麟 V10 部署 OceanBase:故障速查与验收清单
linux·数据库·oceanbase·麒麟
云贝贝贝4 天前
白天稳如狗半夜就抖:OceanBase 合并转储把读写延迟顶了上去
数据库·sql·oceanbase
库库的数据库笔记4 天前
国产信创数据库的MySQL兼容性深度对比解析
大数据·数据库·mysql·oceanbase·政务
NineData6 天前
MySQL 迁移到 OceanBase 怎么做?NineData 全量迁移、CDC 实时同步与数据校验指南
数据库·mysql·oceanbase
TiDB 社区干货传送门7 天前
善战者无赫赫之功:消费金融核心系统的数据库选型与升级路径
tidb·分布式数据库·消费金融·htap·数据库选型
运维小斌8 天前
麒麟 V10 ARM64 离线部署 OceanBase:8 步实施手册
linux·数据库·oceanbase·麒麟
OceanBase数据库官方博客11 天前
OceanBase 亮相亚马逊云科技峰会分享全球化实践(技术解析与实践)
科技·oceanbase
OceanBase数据库官方博客13 天前
被 VLDB 2027接收OceanBase 最新论文让数据库基(技术解析与实践)
数据库·人工智能·oceanbase
knqiufan19 天前
MiniMax Code 接入 PowerContext:构建跨会话与跨 Agent 的项目上下文底座
ai·oceanbase·minimax·powercontext
最笨的羊羊19 天前
Oceanbase数据库系列之:向量数据库核心知识
数据库·oceanbase