本文将总结 Oracle 迁移到 OB 4.x 过程中,那些还不兼容的 DDL 语法。

作者:夏彬胜,爱可生 DBA 团队成员,熟悉 OceanBases,Oracle 等数据库。想到和得到,中间还有个做到

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 900 字,预计阅读需要 3 分钟。

将 Oracle 数据迁移至 OceanBase(Oracle 模式)可以通过 OMS 或 DSG 等工具。无论哪种,本质上就是获取 Oracle 端的 DDL 语句进行改造,然后发往 OB 目标端进行写入,其中最大问题就是 OB 对 Oracle 的语法的兼容程度。

OMS 迁移

1. 约束类

不支持 references_clause 子句定义外键,会忽略该 option。

references_clause:
REFERENCES [ schema_name. ] object [ (column [, column ]...) ][on delete { cascade | set null } ]

不支持 constraint_state 约束状态属性,会忽略该 option。

constraint_state:
[ [NOT] DEFERRABLE [INITIALLY {IMMEDIATE | DEFERRED}]
| INITIALLY { IMMEDIATE | DEFERRED } [ NOT ] [ DEFERRABLE ]
][ rely | norely ]
[ using_index_clause ][ enable | disable ]
[ VALIDATE | NOVALIDATE ][ exceptions_clause ]

2. 索引类

不支持 bitmap_join_index_clause 子句定义 BITMAP INDEX 会报错。关键字 BITMAP INDEX 位图索引,会忽略 BITMAP,创建普通索引。

bitmap_join_index_clause:
[ schema.]table
( [ [ schema. ]table. | t_alias. ]column
[ ASC | DESC ], [ [ schema. ]table. | t_alias. ]column
[ ASC | DESC ]
]...
)
FROM [ schema. ]table [ t_alias ], [ schema. ]table [ t_alias ]
]...
WHERE condition
[ local_partitioned_index ] index_attributes

3. 索引表空间

同步的 DDL 中包含以下属性的定义,则这些属性不会被解析和转换,最终会被忽略:

Global 索引分区定义 RANGE 分区 index_partitioning_clause 中的 segment_attributes_clause 子句指定物理属性和表空间存储,会忽略该 option。

index_attributes:
[ { physical_attributes_clause
| logging_clause
| ONLINE
| TABLESPACE { tablespace | DEFAULT }
| index_compression
| { SORT | NOSORT }
| REVERSE
| VISIBLE | INVISIBLE
| partial_index_clause
| parallel_clause
}...
]

4. 表分区

不支持 enable_disable_other_clause 子句定义启用或禁用与表关联的所有触发器、启用禁用表锁、启用或禁用查询 CONTAINER MAP 映射后的表、启用或禁用该 CONTAINERS 的表,会报错。

enable_disable_other_clause:
{ ENABLE | DISABLE }
{ TABLE LOCK | ALL TRIGGERS | CONTAINER_MAP | CONTAINERS_DEFAULT }

不支持 set_subpartition_template 子句为每个表分区创建或替换现有的默认 RANGE、LIST 或 HASH 子分区,会报错。

set_subpartition_template:
SET SUBPARTITION TEMPLATE
{ ( range_subpartition_desc [, range_subpartition_desc]... )
| ( list_subpartition_desc [, list_subpartition_desc]... )
| ( individual_hash_subparts [, individual_hash_subparts]... )
| ()
| hash_subpartition_quantity
}
modify_table_partition:
{ modify_range_partition
| modify_hash_partition
| modify_list_partition
}

不支持 exchange_partition_subpart 子句来交换数据和索引 segment,会报错。

exchange_partition_subpart:
EXCHANGE { partition_extended_name
| subpartition_extended_name
}
WITH TABLE [ schema. ] table
[ { INCLUDING | EXCLUDING } INDEXES ][ { with | without } validation ]
[ exceptions_clause ] update_index_clauses [ parallel_clause ] ]
[ CASCADE ]

不支持 parallel_clause 子句更改表中查询和 DML 的默认并行度,会忽略该 option。

不支持使用 CREATE TABLE DDL 创建分区时, SUBPARTITION TEMPLATE 和 SUBPARTITION subpartiton_name VALUES (int) 子句同时存在的情况。

5. COMMENT 注释

不支持 COMMENT ON MATERIALIZED VIEW 。

6. RENAME 表

迁移过程中需要确认是否存在 RENAME 表对象。

7. TRUNCATE 表

迁移过程中不能做 DDL 操作,表分区创建以及表分区删除和 TRUNCATE 均不能进行。

OMS 迁移中确认支持的 DDL

  1. 创建表 CREATE TABLE

    包括分区表,不包括 CREATE TABLE AS SELECT。

  2. 删除表 DROP TABLE
  3. 清空表 TRUNCATE TABLE
  4. 添加分区 ADD PARTITION

    支持添加一级分区和二级分区。其中一级和二级分区均支持添加 RANGE/LIST 分区,不支持添加 HASH 分区。

  5. 删除分区 DROP PARTITION

    支持删除单个或多个分区,以及删除二级分区。

  6. 清空分区 TRUNCATE PARTITION

    支持清空单个或多个分区,以及清空二级分区。

  7. 表重命名 RENAME TABLE 或 ALTER TABLE RENAME

  8. 添加列 ALTER TABLE ADD COLUMN
  9. 修改列 ALTER TABLE MODIFY COLUMN

使用 DSG 工具迁移

DSG 工具会在 Oracle 端获取 DDL 然后直接传输到 OB 进行写入,其中需要注意的兼容问题:Oracle 源端导出的 DDL 语句,会存在 EDITIONABLE 关键字。

DSG 工具导出的 DDL 语句存在 EDITIONABLE 关键字(包括:VIEW、TABLE、PROCEDURE 等),到 OB 端都无法执行,需要进行过滤。例如:

CREATE OR REPLACE -FORCE EDITIONABLE- VIEW view_name AS
SELECT column1, column2, ...
FROM table_name
WHERE condition;

其中的 FORCE EDITIONABLE 到 OB(Oracle 模式)下将支持,需要额外处理。

在使用 DSG 工具进行 Oracle 到 OB 的对象迁移时,建议使用 DBCAT。