首批通过分布式安全可靠测评,为关键业务系统打造
Oracle 数据库离线迁移至 OceanBase 数据库 Oracle 模式的参考手册
更新时间:2026-06-01 09:21
本文介绍 Oracle 迁移 OceanBase Oracle 的具体步骤及注意事项等。
Oracle 迁移至 OceanBase Oracle 主要包括 SCHEMA 迁移和数据迁移。
查询 Oracle 中对象依赖关系
可以查询导出成 excel 备用。如后续因依赖关系复杂编译困难,可以参考。
查询所有对象依赖关系。
SELECT owner,type,name,referenced_owner,referenced_type,referenced_name
FROM dba_dependencies t
WHERE owner IN ('ALVIN');
查询跨 SCHEMA 间的依赖(如有)。
SELECT owner,type,name,referenced_owner,referenced_type,referenced_name
FROM dba_dependencies t
WHERE owner IN ('ALVIN')
and owner <> referenced_owner
-- and referenced_type not in ('TABLE','SEQUENCE')
-- and REFERENCED_OWNER in ('ALVIN')
ORDER BY owner,type,name,referenced_owner,referenced_type,referenced_name;
准备迁移 Oracle 数据库用户
如遇到权限问题可以尝试通过如下方式创建迁移用户或授予权限。
CREATE USER SettleAdmin IDENTIFIED BY ALVIN;
GRANT CONNECT TO ALVIN;
GRANT RESOURCE TO ALVIN;
GRANT CREATE VIEW TO ALVIN;
GRANT DBA TO ALVIN;
GRANT SELECT ANY TABLE TO ALVIN;
GRANT SELECT ANY DICTIONARY TO ALVIN;
GRANT SELECT_CATALOG_ROLE TO ALVIN;
OMS 迁移用户参考 用户权限说明。
创建 Oracle 租户
Oracle/OceanBase 数据库 Oracle 模式通过如下方式查询字符集。
SELECT value FROM v$nls_parameters WHERE parameter = 'NLS_CHARACTERSET';
注意
OceanBase Oracle 需要和 Oracle 原库字符集保持一致。
SCHEMA 迁移
从 Oracle 数据库导出 SCHEMA
推荐使用 DBCat 从 Oracle 数据库中导出 SCHEMA (所有对象定义),如有需要改成 OceanBase 数据库语法,此工具导出时会自动处理。
以 Oracle 连接信息 alvin/alvin@10.10.20.20:1521/orcl 为例,根据文档 DBCat 工具从部署到实践 部署好 DBCat 环境后,可以通过如下命令导出全部 SCHEMA,可根据文档选择合适的 OceanBase 数据库版本,如 oboracle420。
./dbcat convert -H 10.10.20.20 -P 1521 -u alvin -p alvin --service-name orcl -D alvin --from oracle11g --to oboracle420 --all
导出结果如下。
ls -1 xxx/dbcat-2.1.0-RELEASE/output/dbcat-2020-10-10-202000/ALVIN
FUNCTION-schema.sql
PACKAGE BODY-schema.sql
PACKAGE-schema.sql
SEQUENCE-schema.sql
TABLE-schema.sql
TYPE BODY-schema.sql
TYPE-schema.sql
VIEW-schema.sql
推荐的 JDK 版本:
Oracle JDK 1.8.0_3xx。 OpenJDK 1.8 最新的小版本 (OpenJDK 1.8 部分小版本存在严重的 GC Bug)。
导入 SCHEMA 到 OceanBase Oracle
通过 OBLOADER 导入(推荐)
OceanBase 官网下载 OceanBase 导数工具 (ob-loader-dumper,导数工具 v4.2.1 及以后的版本不区分企业版和社区版)。
配置好 Java 环境变量,解压后即可使用。
unzip ob-loader-dumper-4.2.x-RELEASE.zip
cd ob-loader-dumper-4.2.x-RELEASE
以 OceanBase 数据库连接信息 obclient -h10.10.20.21 -P2883 -uALVIN@oboracle#obcluster -pxxx 为例,通过如下命令配置变量。
DB_HOST=10.10.20.21
DB_PORT=2883
DB_USER=ALVIN@oboracle#obcluster
DB_PASSWORD=xxx
DB_NAME=alvin
通过如下命令逐个导入 SQL 文件。
推荐按依赖关系导入各对象,如按此顺序导入,SEQUENCE -> TABLE -> TYPE -> VIEW -> FUNCTION/PROCEDURE/PACKAGE...,并可重复导入。
cd ob-loader-dumper-4.2.x-RELEASE/
DB_OUTPUT=./output/dbcat-2020-10-10-202000/ALVIN/"PACKAGE BODY-schema.sql"
LOG_PATH=./output/20200101_1_ALVIN_log_TABLE/
mkdir -p "${LOG_PATH}"
./bin/obloader -h ${DB_HOST} -P ${DB_PORT} -u ${DB_USER} -p ${DB_PASSWORD} -D ${DB_NAME} -f "${DB_OUTPUT}" --log-path "${LOG_PATH}" --mix --all
更多信息参考 导数工具命令行选项。
推荐的 JDK 版本: Oracle JDK 1.8.0_3xx。 OpenJDK 1.8 最新的小版本 (OpenJDK 1.8 部分小版本存在严重的 GC Bug)。
通过 OBClient 导入
适用场景:
仅有少量 SQL 文件且 PROCEDURE/FUNCTION/PACKAGE 等复杂对象较少时,且数据量不大的情况。
TIME_FORMAT_w='+%Y%m%d_%w_%H%M%S'
TIME_STR="$(date "${TIME_FORMAT_w}")"
DB_TYPE=OceanBase
DB_HOST=10.10.20.20
DB_PORT=2883
DB_USER=SYS@oboracle#obcluster
DB_PASSWORD=xxx
DB_NAME=SYS
SQL_FILE=xxx.sql
obclient -h${DB_HOST} -P${DB_PORT} -u${DB_USER} -p${DB_PASSWORD} ${DB_NAME} -A -c -e "source ${SQL_FILE}" &> "${DB_TYPE}_${DB_NAME}_${SQL_FILE}_${TIME_STR}.log"; wc -l "${DB_TYPE}_${DB_NAME}_${SQL_FILE}_${TIME_STR}.log"
SQL_FILE=yyy.sql
obclient -h${DB_HOST} -P${DB_PORT} -u${DB_USER} -p${DB_PASSWORD} ${DB_NAME} -A -c -e "source ${SQL_FILE}" &> "${DB_TYPE}_${DB_NAME}_${SQL_FILE}_${TIME_STR}.log"; wc -l "${DB_TYPE}_${DB_NAME}_${SQL_FILE}_${TIME_STR}.log"
...
通过 ODC 导入
适用场景: 仅有少量 SQL 文件且 PROCEDURE/FUNCTION/PACKAGE 等复杂对象较少时,且数据量不大的情况。
对比迁移前后各数据库对象类型总数
在 Oracle 数据库和 OceanBase 数据库中分别执行如下 SQL 对比各数据库对象类型总数,避免因对象间依赖等原因造成少迁移对象。
a. 如因依赖原因导致对象创建失败,可以多次重复导入以确保对象创建成功。
b. 如因语法错误导致对象创建失败,可以逐个逐步排查语法不兼容处。
c. 如因跨 SCHEMA 间的依赖,可以创建依赖的 SCHEMA 的对象后,再回过来重新创建对象。
执行如下 SQL(对比各数据库对象类型总数)。
SELECT
t.owner,
t.object_type,
t.status,
COUNT(1)
FROM
dba_objects t
where
t.owner IN (
'ALVIN'
)
GROUP BY
t.owner,
t.object_type,
t.status
ORDER BY
t.owner,
t.object_type,
t.status;
对比迁移前后 Oracle 中对象状态为 INVALID 的对象明细
在 Oracle 数据库和 OceanBase 数据库中分别执行如下 SQL 查看并对比 INVALID 的对象。
当迁移到 OceanBase Oracle 后,如果发现对象状态是 INVALID,先查看原数据库对象状态。以避免迁移后发现 OceanBase 中对象状态是 INVALID,排查半天后才发现在原库中就是 INVALID。
执行如下 SQL(查看并对比 INVALID 的对象)。
SELECT
t.owner,
t.object_type,
t.status,
t.object_name
FROM
dba_objects t
where
t.owner IN (
'ALVIN'
)
and t.status IN ('INVALID')
ORDER BY
t.owner,
t.object_type,
t.status;
编译 INVALID 的对象
语法同 Oracle。
以编译 PACKAGE 为例,可以通过如下 SQL 编译。
如果对象依赖关系复杂,可以参考上面查询的 Oracle 数据库中的对象依赖关系,可以逐个编译或解决对象报错。
ALTER PACKAGE pkg_test_compile COMPILE SPECIFICATION;
ALTER PACKAGE pkg_test_compile COMPILE BODY;
ALTER PACKAGE pkg_test_compile COMPILE;
也可以使用下面的批量编译的方法来批量编译当前用户下所有无效对象。
注意
为方便观察单个 PL 对象编译时间等,如下仅批量输出 SQL,复制后批量执行即可
SELECT * FROM user_errors;
SET SERVEROUTPUT ON;
BEGIN
FOR obj IN (SELECT object_name, object_type
FROM user_objects
WHERE object_type IN ('PACKAGE','PACKAGE BODY','TRIGGER','PROCEDURE','FUNCTION','TYPE')
AND status = 'INVALID' )
LOOP
BEGIN
IF obj.object_type = 'PACKAGE' THEN
dbms_output.put_line('ALTER PACKAGE ' || obj.object_name || ' COMPILE SPECIFICATION;');
ELSIF obj.object_type = 'PACKAGE BODY' THEN
dbms_output.put_line('ALTER PACKAGE ' || obj.object_name || ' COMPILE BODY;');
ELSE
dbms_output.put_line('ALTER ' || obj.object_type || ' ' || obj.object_name || ' COMPILE;');
END IF;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Failed to compile ' || obj.object_type || ' "' || obj.object_name || '": ' || SQLERRM);
END;
END LOOP;
END;
/
SELECT * FROM user_errors;
编译完成后可以通过如下 SQL 查看各对象是否还有报错信息。如仍有报错信息,修复问题后再按如上步骤编译一下。
SELECT * FROM user_errors;
或者
SELECT * FROM all_errors WHERE owner = 'ALVIN';
OceanBase 数据库 V4.2.3+ 版本 DDL 执行编译结果落盘和缓存
如使用 OceanBase 数据库 V4.2.3.x 及以上版本时,OceanBase Oracle PROCEDURE/PACKAGE 等 PL 较多且执行时编译慢,导致 SQL 执行慢或页面响应时间较长等问题,可参见文档 OceanBase Oracle 存储过程 DDL 执行编译结果落盘和缓存 进行优化。
数据迁移
小数据量
当单表数据量相对较少时 (如小于 1GB),可以通过常用 Oracle 数据库的客户工具将数据按表分别导出成纯 INSERT SQL 文件,再通过如下命令导入。
cd ob-loader-dumper-4.2.x-RELEASE/
DB_OUTPUT=./output/data/ALVIN/"data.sql"
LOG_PATH=./output/20200101_1_ALVIN_log_data/
mkdir -p "${LOG_PATH}"
./bin/obloader -h ${DB_HOST} -P ${DB_PORT} -u ${DB_USER} -p ${DB_PASSWORD} -D ${DB_NAME} -f "${DB_OUTPUT}" --log-path "${LOG_PATH}" --mix --all
大数据量
当存在大数据量数据需要离线迁移数据时,且已安装 OAT/OCP 或有 16CPU 64GB 内存以上的服务器时,推荐安装并使用 OMS 进行数据迁移。如需协助请联系 OceanBase 技术支持获取相关资源。
应用代码修改
以 Java 应用为例,需要将应用中依赖 Oracle JDBC 驱动的接口类改标准 JDBC 接口 (e.g. java.sql.*) 或 OceanBase JDBC 对应的接口类。 可以参考 OceanBase Connector/J。
引用 OceanBase JDBC 驱动
方式一:使用 Maven 配置自动下载使用
Maven 官方地址:https://central.sonatype.com/artifact/com.oceanbase/oceanbase-client/overview。
pom.xml 相关配置如下,建议使用最新版本。
<dependency>
<groupId>com.oceanbase</groupId>
<artifactId>oceanbase-client</artifactId>
<version>2.4.11</version>
</dependency>
方式二:直接下载
建议使用最新版本:https://repo1.maven.org/maven2/com/oceanbase/oceanbase-client/
如:
https://repo1.maven.org/maven2/com/oceanbase/oceanbase-client/2.4.11/oceanbase-client-2.4.11.jar
JDBC 连接串
OceanBase 数据库 Oracle 模式连接配置大致如下,具体参数根据需要参考 OceanBase Connector/J 。
url=jdbc:oceanbase://10.x.x.x:2883/alvin?usePieceData=true&rewriteBatchedStatements=true&allowMultiQueries=true&useServerPrepStmts=true&useCursorFetch=true&defaultFetchSize=100&socketTimeout=3600000&connectTimeout=60000
username=ALVIN@oboracle#obcluster
password=xxx
driver-class-name=com.oceanbase.jdbc.Driver
适用版本
OceanBase 数据库 V3.2.x、V4.2.x 版本。