问题现象
OceanBase 数据库 Oracle 模式发起表级恢复任务,恢复的表存在用户自定义名字的主键约束,该主键约束的名字在表级恢复的目标 user 下存在有重命的约束,主键约束的约束名冲突导致该表恢复失败。
关键诊断信息
触发条件
OceanBase 数据库 Oracle 模式发起表级恢复任务,恢复的表存在用户自定义名字的主键约束,该主键约束的名字在表级恢复的目标 user 下存在有重命的约束,导致该表恢复失败。
事前巡检
Oracle 模式,执行表级恢复前,需要先检查恢复的表主键约束名是用户自定义的:如果表的主键约束名是用户自定义的,则需要保证恢复的目标 user 下不存在同名约束。若存在同名约束,则这张表会恢复失败。
在恢复的目标 user 下,执行以下 SQL 查询是否存在同名约束。
-- 其中 xxxx 是主键约束的名字 SELECT owner, constraint_name, table_name FROM all_constraints where constraint_name = 'xxxx';若目标 user 下,存在同名的约束:若想要表级恢复要正常恢复到目标 user 的话,则需要将目标用户下这个重名约束改名,具体需要。
a. 先删除重名约束。
ALTER TABLE table_name DROP CONSTRAINT constraint_name;b. 然后换名重新创建约束。
ALTER TABLE table_name ADD CONSTRAINT new_constraint_name;
事后诊断
查看失败的表级恢复导表任务。
-- 其中 $tenant_id 是目标恢复的目标租户 id
select * from CDB_OB_IMPORT_TABLE_JOB_HISTORY where tenant_id= '$tenant_id' and result = 'FAILED' \G;
若存在失败的表级恢复任务记录,且失败的任务记录中包括这样的信息 COMMENT: OBE-02264: name already used by an existing constraint。
-- 失败的表级恢复任务记录
*************************** 1. row ***************************
TENANT_ID: ***
TASK_ID: **
JOB_ID: **
SRC_TENANT_ID: **
SRC_TABLESPACE: NULL
SRC_TABLEGROUP: NULL
SRC_DATABASE: src_database
SRC_TABLE: src_table
SRC_PARTITION: NULL
TARGET_TABLESPACE: NULL
TARGET_TABLEGROUP: NULL
TARGET_DATABASE: target_database
TARGET_TABLE: target_table
TABLE_COLUMN: 18
STATUS: FINISH
START_TIMESTAMP: 2025-02-24 15:52:10.666907
COMPLETION_TIMESTAMP: 2025-02-24 15:53:10.895031
CUMULATIVE_TS: **
TOTAL_INDEX_COUNT: **
IMPORTED_INDEX_COUNT: **
FAILED_INDEX_COUNT: **
TOTAL_CONSTRAINT_COUNT: **
IMPORTED_CONSTRAINT_COUNT: **
FAILED_CONSTRAINT_COUNT: **
TOTAL_REF_CONSTRAINT_COUNT: **
IMPORTED_REF_CONSTRAINT_COUNT: **
FAILED_REF_CONSTRAINT_COUNT: **
RESULT: FAILED
COMMENT: OBE-02264: name already used by an existing constraint
需要进一步确认恢复的原表的主键约束,在表级恢复的目标用户下存在有同名约束: 在目标用户下执行以下 SQL, 确认恢复的目标 user 下存在同名约束。
SELECT owner, constraint_name, table_name FROM all_constraints where table_name = '$table_name';
问题原因
问题根因是 OceanBase 数据库的 Oracle 模式约束名是唯一的,不同的表不支持约束名相同(该行为与 Oracle 一致)。
OceanBase 数据库 Oracle 模式发起表级恢复任务,恢复的表存在用户自定义名字的主键约束,该主键约束的名字在表级恢复的目标 user 下存在有重命的约束,导致该表恢复失败。
问题的风险及影响
Oracle 模式,表级恢复要恢复的表主键约束在目标 user 下存在约束名冲突,导致该表恢复失败。
修改掉目标 user 中重名约束的名字,表即可正常恢复。
影响租户
影响 OceanBase 数据库中的 Oracle 租户,对于 SYS 租户和 MySQL 租户无影响。
影响版本
OceanBase 数据库企业版 V4.2.0 GA(oceanbase-4.2.0.0-100010082023083014)及之后版本、V4.2.1 GA(oceanbase-4.2.1.0-100000182023092722)及之后版本、V4.2.2 GA(oceanbase-4.2.2.0-100000082024011317)及之后版本、V4.2.5 GA(oceanbase-4.2.5.0-100000082024102022)及之后版本、V4.3.0(oceanbase-4.3.0.0-100000072024020200)及之后版本、V4.3.5 GA(oceanbase-4.3.5.0-100000122024123020)及之后版本。
解决方法
若目标 user 下,存在同名的约束:若想要表级恢复要正常恢复到目标 user 的话,则需要将目标用户下这个重名约束改名,具体如下。
先删除重名约束。
ALTER TABLE table_name DROP CONSTRAINT constraint_name;换名重新创建约束。
ALTER TABLE table_name ADD CONSTRAINT new_constraint_name;
规避方式
可以通过以下两种方式规避。
备份数据之前规避,提前避免备份出去表中主键约束名和目标表中的约束的重命名情况,提前修改主键约束的名字。
表级恢复之前规避,避免恢复的目标 user 下存在重命约束,执行表级恢复恢复任务之前提前修改重名约束的名字。