基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
无锁结构变更
更新时间:2026-09-02 11:40:49
为解决变更数据库表结构时的锁表问题,ODC V4.2.0 及之后的版本提供了无锁结构变更功能,该功能可以较好地规避因锁表以致于阻塞业务。本文档旨在介绍如何通过提交无锁变更工单实现数据库无锁结构变更。
注意
无锁结构变更任务仅支持 OceanBase 数据库的 MySQL 模式,并且需要使用企业版或者社区版的 OMS。
背景信息
原理介绍
无锁结构变更的执行过程如下图所示:

说明
如果一个任务涉及多个表,串行变更,即一个表所有步骤处理完成后再进行下一张表的处理。
单表处理步骤包括:
新建影子表:根据用户输入的变更内容,生成一张影子表,影子表的结构为用户最终期望的表结构。
数据同步:将原表的数据通过全量和增量同步的形式同步到影子表中。
数据一致性校验:增量同步过程中,定时去做数据一致性校验。
暂停业务:当原表和影子表数据接近时,暂停业务。根据 OceanBase 数据库版本提供锁定用户和锁定表两种暂停业务方式。lock user 和 lock table 的时间由数据库内核决定,程序不做限制。其中锁定用户在 lock user 成功后会同步 kill 该用户的会话,若 2s 内未 kill 成功,则锁定失败。
数据追平:业务暂停后,增量同步和数据校验一直运行,若 25s 内数据仍未追平,任务将失败退出。
新旧表名切换:数据追平后,rename 原表和影子表,影子表成为新的业务表进行生产业务。
无锁结构变更工单执行流程

用户提交无锁结构变更工单。
对用户输入的 SQL 语句进行预检查。
审批任务流程。
执行无锁结构变更任务。
支持的变更范围
| 分类 | 操作 | 是否支持 | 备注 |
|---|---|---|---|
| 列操作 | 列类型修改 | 是 | |
| 重排列(before/after/first) | 是 | ||
| 转换字符集 | 是 | ||
| 列重命名 | 否 | ||
| 增加列 | 是 | ||
| 删除列 | 是 | ||
| 增加主键列 | 否 | ||
| 主键 | 增加主键 | 是 | 表存在非空唯一键 |
| 修改主键 | 是 | 表存在非空唯一键 | |
| 删除主键 | 是 | 表存在非空唯一键 | |
| 分区 | 删除分区 | 是 | |
| truncate 分区 | 否 | ||
| 重分区 | 是 | ||
| 非分区表改为分区表 | 是 | ||
注意事项
确保数据库磁盘空间充足。
表中必须 存在主键或非空唯一键 且表中 不存在外键。
当前表在执行无锁结构变更时,执行其它 DDL 操作会导致任务失败。
OceanBase MySQL 模式下的表名称不超过 54 个字符。
ODC 连接 OceanBase 社区版数据库时,数据源配置信息中需包含集群名和 SYS 租户账号。
关于表名切换禁写策略,默认仅提供锁定用户方案,部分 OB 版本额外提供锁定表方案。
采用锁定用户(lock user)方案时,需注意如下限制:
执行变更的数据库账号需具备锁定用户的操作权限,通常为
CREATE USER权限,具体所需权限视 OceanBase 数据库版本而定。执行变更的数据库账号不能出现在锁定用户列表中,否则该账号自身的会话会被一并关闭,导致切换表结构时 kill session 失败。
在单次无锁结构变更期间,增加列和删除列不能同时进行。如有需要,请分批次进行变更。
新建无锁结构变更任务
本文以 OceanBase 社区版和企业版 OMS 为例,演示场景为将表 student 中的列 birth 类型修改为 date。该示例所使用的项目名称为 odc_4.2.0,数据库名称为 odc_test,表名称为 student。
(可选)安装 OceanBase 社区版集群。如已完成集群配置,可跳过此步骤。
说明
通过企业版 OMS 创建 OceanBase 数据源时需包含集群名,单机无法创建数据源。具体部署集群的方法请参见 方案二:部署 OceanBase 集群环境。
安装 ConfigServer。ConfigServer 为 OceanBase 和 OBProxy 存取 OceanBase rs_list 的接口, 完成配置 OceanBase ConfigServer 地址后,OceanBase 会自动注册 rs_list 到 ConfigServer。
说明
通过 OCP 部署集群时,可忽略此步骤。OCP 创建的集群会自动设置 OCP 的地址作为 OceanBase ConfigServer。
安装企业版 OMS。本文以企业版 OMS 为例,您可以通过 Docker 获取,您也可以按需选择社区版 OMS 并完成配置。
配置 ODC 元数据信息,启用无锁结构变更。
a. ODC 配置企业版 OMS 信息。
连接 ODC 的元数据库,配置企业版 OMS 的 URL 和登录授权信息。 oms_url 的构成为
http://${oms_host}: ${oms_port},oms_authornazition 的构成为username:password的 Base64 编码。配置完成后,重启 ODC 使配置的企业版 OMS 信息生效。语法格式:
#配置 oms_url update config_system_configuration set `value` = '${oms_url}' where `key` = 'odc.osc.oms.url'; #配置 oms_authornazition update config_system_configuration set `value` = '${oms_authornazition}' where `key` = 'odc.osc.oms.authorization'; #配置 oms_region,例如 cn-anhui update config_system_configuration set value = '${oms_region}' where `key` = 'odc.osc.oms.region'示例:
#配置 oms_url,填写 oms 的访问地址:http://localhost:8089 update config_system_configuration set `value` = 'http://localhost:8089' where `key` = 'odc.osc.oms.url'; #配置 oms_authornazition,如账户为 test,密码为 123456,将 `test:123456` 进行 Base64 编码后为:dGVzdDoxMjM0NTY= update config_system_configuration set `value` = 'dGVzdDoxMjM0NTY=' where `key` = 'odc.osc.oms.authorization'; #配置 oms_region,如安装 oms 时输入的 region 为 cn-anhui,详情见 oms 安装过程 update config_system_configuration set value = 'cn-anhui' where `key` = 'odc.osc.oms.region'
b. 打开无锁结构变更。目前阿里云数据库 OceanBase 已开放无锁结构变更,而对于 OceanBase 社区版,ODC 默认未启用无锁结构变更,需要配置 ODC 元数据库,通过 SQL 语句打开配置。
```shell update config_system_configuration set value = 'true' where `key` = 'odc.features.task.osc.enabled'; ```-
注意
对于 OceanBase 社区版, 在使用 ODC 创建数据源时,需配置 sys 租户。

在 SQL 窗口中,编辑 SQL 语句以创建表 student 到数据库 odc_test 中。
CREATE TABLE `odc_test`.`student` ( `id` int(11) COMMENT 'student id' NOT NULL, `name` varchar(120) COMMENT 'student name' NULL, `birthday` datetime(0) COMMENT 'student birthday' NOT NULL, `province` varchar(120) COMMENT 'student province' NULL, `city` varchar(120) COMMENT 'student city' NULL, `mobile_phone` int COMMENT 'student mobile_phone' NULL, `email` varchar(120) COMMENT 'student email' NULL, `create_time` datetime(0) COMMENT 'update time' NULL, CONSTRAINT `cons_id` PRIMARY KEY (`id`) ) DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci ;锁定账号/锁表。
对于 OceanBasese MySQL V4.2.5 之前的版本,变更数据库表结构时不支持锁表,您需要指定将要锁定的账号,切换新旧表(
Rename)时,ODC 会对锁定的账号执行alter table user lock account命令并关闭会话操作,以关闭锁定账号下的所有进程。
对于 OceanBase MySQL V4.2.5 及之后且 OceanBase MySQL V4.3.0 之前的版本,变更数据库表结构时不再通过锁定账号进行锁表,您需要确认 OBProxy 版本为 V4.3.1 及之后,并在无锁结构变更任务前执行以下操作进行锁表,否则锁表失败。
修改 OBProxy 参数。
alter proxyconfig set proxy_id=1; alter proxyconfig set client_session_id_version=2; alter proxyconfig set enable_single_leader_node_routing = false;修改租户级别参数。
alter system set enable_lock_priority=true;修改支持锁表功能的 OceanBase MySQL 版本范围。
锁表功能默认支持的 OceanBase MySQL 版本范围为 V4.2.5 ~ V4.2.9。如需修改锁表功能支持的版本范围,您可以连接 ODC 的元数据库并执行如下 SQL 语句。
insert into config_system_configuration( key, application, profile, label, description, value) values('odc.osc.support-lock-table-ob-version-json', 'odc', 'default', 'master', 'control odc enable lock table version, default is ["4\\.2\\.[5-9].* "]', '$期望版本范围');其中,
'$期望版本范围'为 JSON 数组,数组元素遵循 Java 通配规则。例如将 OceanBase MySQL 版本范围修改为 V4.2.5 ~ V4.2.9 以及 V4.3.5,其对应 value 值为["4\\\\.2\\\\.[5-9].*", "4.3.5.*"]。验证锁表是否成功,通过 ODC 执行
lock table命令锁定一个临时表后,使用新链接尝试插入数据到临时表中,插入数据被阻塞则表示锁表任务生效。create table test_table(id int not null primary key); session 1: session 2 lock table test_table; insert into test_table values(1); 阻塞中... unlock table test_table; 插入成功
新建无锁结构变更任务。
在 项目 > 全部项目 页面中单击目标项目名称。

在 工单 页签中单击 无锁结构变更 > 新建无锁结构变更。

在 新建无锁结构变更 页面中,输入以下信息,并单击 新建。

信息项 说明 数据库 选择需变更的数据库。 锁定用户 - 如果指定锁定用户,则表名切换之前 ODC 会锁定所指定的数据库账号,并关闭该账号对应的所有会话信息,以保障表名切换期间数据一致性的同时尽可能降低对业务的影响。
- 如果未指定任何账号,ODC 将不会进行任何账号锁定及关闭会话操作,需自主确保切换期间数据的一致性。
注意
- 执行无锁结构变更任务期间,执行该任务的用户不可执行与无锁结构变更相关表的变更操作。
- 执行该任务的数据库账号需具备锁定用户的操作权限,通常为
CREATE USER权限,具体所需权限视 OceanBase 数据库版本而定。 - 请勿将执行该任务的数据库账号指定为锁定用户,否则该账号链接不会被正常终止,导致切换表结构时 kill session 失败。
变更定义 - CREATE TABLE:OceanBasese 不支持的语法需要使用 CREATE 语句。
- ALTER TABLE:OceanBasese V4.0.0 及之后的版本,ALTER TABLE OFFLINE 模式可以使用 ALTER 语句。
SQL 内容 在编辑区中录入 SQL 脚本。 切换表设置 数据一致后将原表切换为目标表。 - 锁表超时时间:切换表过程会锁表,超时未切换完成可能导致执行失败。
- 失败重试次数:超过锁表时间后,未切换完成可自动重试。
- 完成后源表清理策略:选择 重命名不处理,重命名源表,不删除。选择 立即删除,无锁结构变更完成后删除源表。
任务设置 - 执行方式:选择 手动执行/立即执行/定时执行。
- 任务错误处理:
- 停止任务:停止任务为默认方式,运行脚本的过程中出现错误时会停止运行。
- 忽略错误继续任务:选择忽略错误继续任务方式,在运行脚本出现错后将跳过错误语句继续执行。
- 表名切换方式:选择 自动切换/手动切换 表名。
描述 可在 描述 文本框中输入不超过 200 个字符的描述信息,该项为选填项。 任务生成后可以在 工单 > 无锁结构变更 列表中查看任务信息。

查看无锁结构变更任务
访问 工单 > 无锁结构变更,无锁结构变更任务列表中,单击目标任务的名称,查看任务详情。也可以通过操作列的 ··· 对目标任务进行更多操作。
- 执行:当任务执行方式为手动执行时,主动执行该工单。
- 终止:当任务执行方式为周期执行或定期执行时,可通过终止结束该工单。勾选目标工单,可通过上方的批量操作按钮进行批量终止。
- 禁用/启用:当任务执行方式为周期执行或定期执行时,可通过禁用使该任务暂时停止执行,在重新启用后再次生效。
- 编辑:当任务状态为禁用时,可通过编辑对该任务内容进行更新。
- 删除:当任务状态为已完成或终止时,可通过删除对该任务进行删除操作。
- 查看:查看任务内容详情。
- 克隆:复制该任务执行内容,快速生成相同配置的新建任务界面。
- 分享:快速复制该任务的访问地址。

在弹出的任务详情面板中,默认展示该作业的 基本信息 页签,可以查看任务类型、数据库、变量配置、执行方式等信息。

在任务详情面板中,单击 任务流程 页签查看发起任务状态、审批状态、执行状态和执行结果等信息。

在任务详情面板中,单击 执行结果 页签查看任务执行记录。

在任务详情面板中,单击 任务日志 页签查看任务的全部日志和告警日志。
信息项 说明 全部日志 全部日志显示任务的 INFO、ERROR 和 WARN 日志等全量信息。 单击 查找、下载 和 复制 按钮,可查找信息、下载或复制全部日志信息。 告警日志 告警日志单独显示任务的 ERROR 和 WARN 日志。当任务失败时,可通过告警日志查看错误信息。 单击 查找、下载 和 复制 按钮,可查找信息、下载或复制告警日志信息。 