---
title: "迁移 Oracle 数据库的数据至 OceanBase 数据库 Oracle 租户 | OceanBase 文档中心"
description: 迁移 Oracle 数据库的数据至 OceanBase 数据库 Oracle 租户 本文为您介绍如何使用 OceanBase 迁移服务（OceanBase Migration Service，OMS）迁移 Oracle 数据库的数据至 OceanBase 数据库 Oracle 租户。 背景信息 在 OMS 控制台创建…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*L03BS6f-o40AAAAAAAAAAAAADiGDAQ/original) 迁移服务 OMSV 4.2.0 企业版

# 迁移 Oracle 数据库的数据至 OceanBase 数据库 Oracle 租户

更新时间：2025-10-21 14:10:38

本文为您介绍如何使用 OceanBase 迁移服务（OceanBase Migration Service，OMS）迁移 Oracle 数据库的数据至 OceanBase 数据库 Oracle 租户。

## 背景信息

在 OMS 控制台创建从 Oracle 数据库迁移数据至 OceanBase 数据库 Oracle 租户的数据迁移项目，您可以通过结构迁移、全量迁移和增量数据同步，无缝迁移源端数据库中的存量业务数据和增量数据至 OceanBase 数据库 Oracle 租户。

Oracle 数据库支持单主库、单备库和主备库等模式。迁移 Oracle 数据库的数据至 OceanBase 数据库 Oracle 租户的数据库时，不同类型的数据源支持的操作也不同。

| 类型 | 支持的操作 |
| --- | --- |
| 单主库 | 结构迁移 + 全量迁移 + 增量同步+ 全量校验 + 反向增量 |
| 单备库 | 结构迁移 + 全量迁移 + 增量同步 + 全量校验 |
| 主备库 | 主库：支持反向增量 备库：支持结构迁移 + 全量迁移 + 增量同步 + 全量校验 |

## 前提条件

- 已在目标端 OceanBase 数据库 Oracle 租户创建对应的 Schema。
 - Oracle 源实例必须开启 Archive Log，并且在 OMS 增量复制前已经切换过 LogFile。
 - Oracle 源实例必须已经安装并可正常使用 LogMiner 工具。

  您可以通过 LogMiner 工具获取 Oracle 归档日志文件中的具体内容。
 - 已为源端 Oracle 数据库和目标端 OceanBase 数据库 Oracle 租户创建专用于数据迁移任务的数据库用户，并为其赋予了相关权限。详情请参见 [创建数据库用户](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091344)。
 - 确认 Oracle 实例已开启数据库级别或者表级别的补偿日志。
 - 开启数据库级别的 PK 和 UK 补偿日志，当无需同步的表产生较多不必要的日志时，会增加 LogMiner Reader 拉取日志的压力和 Oracle 自身的压力。所以，OMS 支持 Oracle 数据库仅开启表级别的 PK 和 UK 补偿日志。但是，如果在创建迁移任务时，针对非 PK 列或 UK 列设置了 ETL 过滤，请开启对应列的补偿日志，或者直接开启所有列的补偿日志。
 - Oracle 机器和 OMS 机器之间需要进行时钟同步（例如配置 NTP 服务），否则会存在数据风险。如果是 Oracle RAC，则多个 Oracle 实例之间也需要进行时钟同步。

## 使用限制

- **源端数据库的操作限制**

  **请勿在结构迁移和全量迁移阶段执行库或表结构变更的 DDL 操作，否则可能造成数据迁移项目中断。**
 - OMS 支持的 Oracle 数据库版本为 10G/11G/12C/18C/19C，12C 及之后版本包含数据库容器（Container Database，CDB）和可插拔数据库（Pluggable Database，PDB）。
 - OMS 仅支持迁移普通表和视图。
 - OMS 仅支持迁移库名、表名和列名为 ASCII 码且不包含特殊字符（包括 .|"'`()=;/& 和换行）的对象。
 - 目标端是数据库的情况下，OMS 不支持目标端存在 Trigger。如果存在，可能导致数据迁移失败。
 - 数据类型的限制

     - 不支持表中全部列均为 LOB 类型（BLOB/CLOB/NCLOB）的增量数据迁移。
     - 对于无主键且包含 LOB 类型字段的表，反向增量会出现数据质量问题。
 - 数据源标识和用户账号等，在 OMS 系统内全局唯一。
 - Oracle 数据库的增量日志解析最大支持 5T/天。
 - Oracle 数据库 11G 及之前版本不支持创建超过 30 个字节的数据库对象。在反向增量步骤中，请注意不能在 OceanBase 数据库 Oracle 租户中创建大于本限制的数据库对象。
 - OMS 不支持迁移 Oracle 数据库 12C 及之后版本中超过 30 个字节的数据库对象（包括 Schema、表和列等）。如果您需要迁移超过 30 个字节的数据库对象，请参见 [如何迁移超过 30 个字节的 Oracle 数据库对象](https://www.oceanbase.com/knowledge-base/oms-ee-1000000000234455)。
 - OMS 不支持源端 Oracle 数据库执行某些 `UPDATE` 命令。以下示例为一个不支持的 `UPDATE` 命令。

  ```sql
  UPDATE TABLE_NAME SET KEY=KEY+1;

  ```

  上述示例中，`TABLE_NAME` 是表名，`KEY` 是定义为主键的 NUMERIC 类型的列。

## 注意事项

- **当录入的 Oracle 数据库为单备库或主备库模式时，如果 Oracle 主库和备库的运行实例数不同，可能导致少拉取某些实例的增量日志。您需要手动设置 Store 组件的参数，以指定增量从备库拉取时需要拉取的实例的增量日志。操作方式如下：**

     1. Store 组件启动后马上将其停止。
     2. 在 Store 组件的 **更新配置** 页面，新增参数 `deliver2store.logminer.instance_threads` 来设置需要拉取哪些实例的日志。

       多个 thread 之间使用 | 分隔。例如，1|2|3。更新组件的详情请参见 [使用 OMS 从 Oracle 备库增量同步时丢失 Archive 日志](https://www.oceanbase.com/knowledge-base/oms-ee-1000000000266018?back=kb)。
     3. 设置参数后，重启 Store 组件。
     4. 5 分钟后，执行 `grep 'log entries from' connector/connector.log`，即可查看拉取了哪些实例的日志（thread 字段表示拉取到的是哪个实例的日志）。
 - **当需要进行 Oracle 数据库的增量同步时，Oracle 数据库单个归档文件的大小建议小于 2GB。单个归档文件过大，会存在如下风险：**

     - 单个归档文件越大，拉取的耗时比线性增长更大。
     - 录入的 Oracle 数据库为单备库或主备库模式时，增量是从备库拉取，此时只能拉取归档文件。当归档文件生成后才能拉取，归档文件越大，也就意味着在处理该归档文件之前已经延迟较久，并且处理该大的归档文件耗时也越久。
     - 单个归档文件越大，在开启相同并发度的拉取时，Store 组件需要的内存也越大。
 - **Oracle 数据库的归档文件保存 2 天以上，否则由于某个时间段归档量陡增或者 Oracle Store 处理异常，准备恢复时没有了归档文件，将无法恢复。**
 - 如果源端 Oracle 数据库存在交换主键的 DML 语句，将导致 OMS 解析日志异常，迁移至目标端时存在数据丢失的问题。交换主键的 DML 语句示例如下：

  ```sql
  UPDATE test SET c1=(CASE WHEN c1=1 THEN 2 WHEN c1=2 THEN 1 END) WHERE c1 IN (1,2);

  ```
 - Oracle 实例的的字符集配置可以为 AL32UTF8、AL16UTF16、ZHS16GBK 和 GB18030。如果源端字符集为 UTF-8，建议目标端使用兼容源端的字符集（例如，UTF-8、UTF-16 等），避免产生因字符集不兼容导致目标端出现乱码等问题。
 - OMS 从 Oracle 备库拉取增量数据时，如果您选择的迁移类型中包含增量同步和反向增量，而增量数据拉取出现异常，您可以尝试在主库执行 `ALTER SYSTEM SWITCH LOGFILE`，以便推动 OMS 正常工作。
 - 迁移 Oracle 数据库的数据至 OceanBase 数据库 Oracle 租户时，禁止所有表进行导入、导出、Alter Table、FlashBack Table、分区分裂或合并等会导致 ROWID 变更的操作。

  当源端 Oracle 数据库存在更新分区键、合并分区等影响 RowID 行为的操作时，目标端 OceanBase 数据库 Oracle 租户增加了隐藏列依赖 RowID，可能导致数据存在丢失的风险。
 - 节点之间的时钟不同步，或者电脑终端和服务器之间的时钟不同步，均可能导致延迟时间（增量同步/反向增量）不准确。

  例如，如果时钟早于标准时间，可能导致延迟时间为负数。如果时钟晚于标准时间，可能导致延迟。
 - 由于中国曾经实行夏令时的历史原因，导致 Oracle 数据库至 OceanBase 数据库 Oracle 租户的增量同步中，1986 年~1991 年的夏令时开始和结束的日期，以及 1988 年 4 月 10 日~ 4 月 17 日，`TIMESTAMP(6) WITH TIME ZONE` 类型，源端和目标端可能存在 1 小时的时间差。
 - Oracle 数据库至 OceanBase 数据库 Oracle 租户的反向增量中，当源端 OceanBase 数据库 Oracle 租户为 3.2.x 之前的版本且具有全局唯一索引的多分区表时，如果您更新了表的分区键的值，可能导致数据迁移过程中丢失数据。
 - 目标端 OceanBase 数据库 Oracle 租户的版本小于 2.2.70 时，切换流程补充外键、Check 等对象有不兼容的风险。
 - 在未开启同步 DDL 的情况下，如果您变更目标端的唯一索引，需要重启增量同步组件，否则可能存在数据不一致的问题。
 - 如果数据迁移项目未启用正向切换，请删除目标端数据库对应的唯一索引和伪列。如果不删除唯一索引和伪列，会导致无法写入数据，以及往下游导入数据时，会重新生成伪列，导致与源端数据库的伪列发生冲突。

  如果数据迁移项目已启用正向切换，OMS 会根据数据迁移项目的类型，自动删除隐藏列和唯一索引。详情请参见 [数据迁移服务隐藏列机制说明](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091479)。
 - 对于 Oracle 数据库至 OceanBase 数据库 Oracle 租户的增量同步，如果有新增的无主键表迁移，OMS 不会自动删除在 OceanBase 数据库 Oracle 租户目标端添加的隐藏列和唯一索引。在进行反向迁移前，请您手动删除。

  您可以查看 `logs/msg/manual_table.log` 文件，确认增量同步阶段添加的无主键表。
 - 当源端和目标端的字符编码配置不同时，结构迁移会提供字段长度定义扩大的策略。例如字段长度 1.5 倍扩大，长度单位从 BYTE 转为 CHAR 等。

  转换后可以保证源端不同字符集中的数据能成功迁移至目标端，但割接后反向增量可能会出现数据超长无法写回源端的问题。
 - ​如果源端存在包含时区信息的数据类型（例如 TIMESTAMP WITH TIME ZONE），请您确保目标端数据库支持并存在源端对应的时区，否则将导致数据迁移过程中产生数据不一致的问题。
 - 库表汇聚场景下：

     - 建议您使用匹配规则的方式映射源端和目标端的关系。
     - 建议您自行在目标端创建表结构。如果使用 OMS 创建，请在结构迁移步骤跳过部分失败对象。
 - 请检查 Oracle 数据库回收站内的对象。当对象大于 100 时，容易造成内部表查询超时，请进行回收站的对象清理工作。

     - 检查回收站是否打开。

      ```sql
      SELECT Value FROM V$parameter WHERE Name = 'recyclebin';

      ```
     - 检查回收站内对象的数量。

      ```sql
      SELECT COUNT(*) FROM RECYCLEBIN;

      ```
 - 如果创建数据迁移项目时，您仅配置了 **增量同步**，OMS 要求源端数据库的归档日志保存 48 小时以上。

  ​如果创建数据迁移项目时，您配置了 **全量迁移** + **增量同步**，OMS 要求源端数据库的归档日志至少保留 7 天以上。否则数据迁移可能因为无法获取增量日志导致数据迁移项目失败，甚至导致源端和目标端数据不一致。
 - 如果源端或目标端存在仅大小写不同的表对象，可能会因为源端或目标端大小写不敏感导致数据迁移的结果不符合预期。

## 数据类型映射

#### 注意

- 目标端为 OceanBase 数据库 Oracle 租户 V4.2.0 之间版本时，CLOB 和 BLOB 类型的数据必须小于 48 MB。

  目标端为 OceanBase 数据库 Oracle 租户 V4.2.0 及之后版本时，CLOB 和 BLOB 类型的数据最大支持 512 MB。
 - 不支持迁移 ROWID、BFILE、XMLType、UROWID、UNDEFINED 和 UDT 类型的数据。
 - 不支持 LONG 或 LONG RAW 类型的表进行增量同步。

| Oracle 数据库 | OceanBase 数据库 Oracle 租户 |
| --- | --- |
| CHAR(n CHAR) | CHAR(n CHAR) |
| CHAR(n BYTE) | CHAR(n BYTE) |
| NCHAR(n) | NCHAR(n) |
| VARCHAR2(n) | VARCHAR2(n) |
| NVARCHAR2(n) | NVARCHAR2(n) |
| NUMBER(n) | NUMBER(n) |
| NUMBER (p, s) | NUMBER(p,s) |
| RAW | RAW |
| CLOB | CLOB |
| NCLOB | - OceanBase 数据库 Oracle 租户 2.2.50 以下版本不支持转换 - OceanBase 数据库 Oracle 租户 2.2.50 及以上版本支持转换为 NVARCHAR2      **说明**     OceanBase 数据库 Oracle 租户中，NVARCHAR2 类型的字段不支持空值。如果源端存在空值，则以字符串 NULL 表示。 |
| BLOB | BLOB |
| REAL | FLOAT |
| FLOAT(n) | - OceanBase 数据库 Oracle 租户 2.2.30 以下版本：NUMBER(n*0.30103) - OceanBase 数据库 Oracle 租户 2.2.30 及以上版本：FLOAT |
| BINARY_FLOAT | BINARY_FLOAT |
| BINARY_DOUBLE | BINARY_DOUBLE |
| DATE | DATE |
| TIMESTAMP | TIMESTAMP |
| TIMESTAMP WITH TIME ZONE | TIMESTAMP WITH TIME ZONE |
| TIMESTAMP WITH LOCAL TIME ZONE | TIMESTAMP WITH LOCAL TIME ZONE |
| INTERVAL YEAR(p) TO MONTH | INTERVAL YEAR(p) TO MONTH |
| INTERVAL DAY(p) TO SECOND | INTERVAL DAY(p) TO SECOND |
| LONG | CLOB    **注意**：该类型不支持增量同步。 |
| LONG RAW | BLOB    **注意**：该类型不支持增量同步。 |

## Oracle 表分区转换

OMS 迁移 Oracle 数据库时，会对业务 SQL 用法进行适配转换，OceanBase 数据库 2.2.30 和 2.2.50 版本对部分 SQL 适配转换方式不同。

#### 说明

本文的分区转换规则适用于所有分区类型。

| 原表定义 | OceanBase 数据库 2.2.30 版本转换输出 | OceanBase 数据库 2.2.50 及以上版本转换输出 |
| --- | --- | --- |
| `CREATE TABLE T_RANGE_0 (`   `A INT,`   `B INT,`   `PRIMARY KEY (B)`   `)PARTITION BY RANGE(A)(`   `....`   `);` | `CREATE TABLE "T_RANGE_0" (`   `"A" NUMBER,`   `"B" NUMBER NOT NULL,`   `PRIMARY KEY ("B", "A")`   `)PARTITION BY RANGE ("A")(`   `....`   `);`   `CREATE UNIQUE INDEX ON "T_RANGE_0"(B);`  - 主键列未包含分区列 - 分区列是物理列 - 加入至主键列，组成联合主键 - 原始的主键列添加全局唯一索引 | `CREATE TABLE "T_RANGE_0" (`   `"A" NUMBER,`   `"B" NUMBER NOT NULL,`   `CONSTRAINT "T_RANGE_10_UK" UNIQUE ("B")`   `)PARTITION BY RANGE ("A")(`   `....`   `);` |
| `CREATE TABLE T_RANGE_10 (`   `"A" INT,`   `"B" INT,`   `"C" DATE,`   `"D" NUMBER GENERATED ALWAYS AS (TO_NUMBER(TO_CHAR("C",'dd'))) VIRTUAL,`   `CONSTRAINT "T_RANGE_10_PK" PRIMARY KEY (A)`   `)PARTITION BY RANGE(D)(`   `....`   `);` | `CREATE TABLE T_RANGE_10 (`   `"A" INT NOT NULL,`   `"B" INT,`   `"C" DATE,`   `"D" NUMBER GENERATED ALWAYS AS (TO_NUMBER(TO_CHAR("C",'dd'))) VIRTUAL,`   `CONSTRAINT "T_RANGE_10_PK" PRIMARY KEY (A, C)`   `)PARTITION BY RANGE(D)(`   `....`   `);` | `CREATE TABLE T_RANGE_10 (`   `"A" INT NOT NULL,`   `"B" INT,`   `"C" DATE,`   `"D" NUMBER GENERATED ALWAYS AS (TO_NUMBER(TO_CHAR("C",'dd'))) VIRTUAL,`   `CONSTRAINT "T_RANGE_10_PK" UNIQUE (A)`   `)PARTITION BY RANGE(D)(`   `....`   `);` |
| `CREATE TABLE T_RANGE_1 (`   `A INT,`   `B INT,`   `UNIQUE (B)`   `)PARTITION BY RANGE(A)(`   `partition P_MAX values less than (10)`   `);` | -- [WARNING] Create global index on no primary key table is unsupported. Object: "GUYUE"."T_RANGE_1" | 支持原表定义 |
| `CREATE TABLE T_RANGE_2 (`   `A INT,`   `B INT NOT NULL,`   `UNIQUE (B)`   `)PARTITION BY RANGE(A)(`   `partition P_MAX values less than (10)`   `);` | `CREATE TABLE "T_RANGE_2" (`   `"A" NUMBER,`   `"B" NUMBER NOT NULL,`   `PRIMARY KEY ("B", "A")`   `)PARTITION BY RANGE ("A")(`   `....`   `);` | 支持原表定义 |
| `CREATE TABLE T_RANGE_3 (`   `A INT,`   `B INT,`   `UNIQUE (A)`   `)PARTITION BY RANGE(A)(`   `....`   `);` | -- [WARNING] Create global index on no primary key table is unsupported. Object: "GUYUE"."T_RANGE_2" | 支持原表定义 |
| `CREATE TABLE T_RANGE_4 (`   `A INT NOT NULL,`   `B INT,`   `UNIQUE (A)`   `)PARTITION BY RANGE(A)(`   `....`   `);` | `CREATE TABLE "T_RANGE_4" (`   `"A" NUMBER NOT NULL,`   `"B" NUMBER,`   `PRIMARY KEY ("A")`   `)PARTITION BY RANGE ("A")(`   `....`   `);` | `CREATE TABLE "T_RANGE_4" (`   `"A" NUMBER NOT NULL,`   `"B" NUMBER,`   `PRIMARY KEY ("A")`   `)PARTITION BY RANGE ("A")(`   `....`   `);` |
| `CREATE TABLE T_RANGE_5 (`   `A INT,`   `B INT,`   `UNIQUE (A, B)`   `)PARTITION BY RANGE(A)(`   `partition P_MAX values less than (10)`   `);` | -- [WARNING] Create global index on no primary key table is unsupported. Object: "GUYUE"."T_RANGE_5" | 支持原表定义 |
| `CREATE TABLE T_RANGE_6 (`   `A INT NOT NULL,`   `B INT,`   `UNIQUE (A, B)`   `)PARTITION BY RANGE(A)(`   `partition P_MAX values less than (10)`   `);` | -- [WARNING] Create global index on no primary key table is unsupported. Object: "GUYUE"."T_RANGE_5" | 支持原表定义 |
| `CREATE TABLE T_RANGE_7 (`   `A INT NOT NULL,`   `B INT NOT NULL,`   `UNIQUE (A, B)`   `)PARTITION BY RANGE(A)(`   `partition P_MAX values less than (10)`   `);` | `CREATE TABLE "T_RANGE_7" (`   `"A" NUMBER NOT NULL,`   `"B" NUMBER NOT NULL,`   `PRIMARY KEY ("A", "B")`   `)PARTITION BY RANGE ("A")(`   `....`   `);` | `CREATE TABLE "T_RANGE_7" (`   `"A" NUMBER NOT NULL,`   `"B" NUMBER NOT NULL,`   `PRIMARY KEY ("A", "B")`   `)PARTITION BY RANGE ("A")(`   `....`   `);` |
| `CREATE TABLE T_RANGE_8 (`   `"A" INT,`   `"B" INT,`   `"C" INT NOT NULL,`   `UNIQUE (A),`   `UNIQUE (B),`   `UNIQUE (C)`   `)PARTITION BY RANGE(B)(`   `partition P_MAX values less than (10)`   `);` | `CREATE TABLE "T_RANGE_8" (`   `"A" NUMBER,`   `"B" NUMBER,`   `"C" NUMBER NOT NULL,`   `PRIMARY KEY ("C", "B"),`   `UNIQUE ("A"),`   `UNIQUE ("B"),`   `UNIQUE ("C")`   `)PARTITION BY RANGE ("B")(`   `....`   `);` | 支持原表定义 |
| `CREATE TABLE T_RANGE_9 (`   `"A" INT,`   `"B" INT,`   `"C" INT NOT NULL,`   `UNIQUE(A),`   `UNIQUE(B),`   `UNIQUE (C)`   `)PARTITION BY RANGE(C)(`   `partition P_MAX values less than (10)`   `);` | `CREATE TABLE "T_RANGE_9" (`   `"A" NUMBER,`   `"B" NUMBER,`   `"C" NUMBER NOT NULL,`   `PRIMARY KEY ("C"),`   `UNIQUE ("A"),`   `UNIQUE ("B")`   `)PARTITION BY RANGE ("C")(`   `....`   `);` | `CREATE TABLE "T_RANGE_9" (`   `"A" NUMBER,`   `"B" NUMBER,`   `"C" NUMBER NOT NULL,`   `PRIMARY KEY ("C"),`   `UNIQUE ("A"),`   `UNIQUE ("B")`   `)PARTITION BY RANGE ("C")(`   `....`   `);` |

## 检查和修改 Oracle 实例的系统配置

您需要进行下述操作：

1. 在源端 Oracle 数据库开启归档模式
 2. 在源端 Oracle 数据库开启补偿日志
 3. （可选）设置 Oracle 数据库的系统参数

### 在源端 Oracle 数据库开启归档模式

```sql
SELECT log_mode FROM v$database;

```

`log_mode` 字段需要是 `archivelog`。否则，您需要根据下述方法进行修改。

1. 执行下述命令，开启归档模式。

   ```sql
   SHUTDOWN IMMEDIATE;
   STARTUP MOUNT;
   ALTER DATABASE ARCHIVELOG;
   ALTER DATABASE OPEN;

   ```
 2. 执行下述命令，查看归档日志的路径和配额。

   检查 `recovery file` 的路径和配额，建议 `db_recovery_file_dest_size` 的配置值尽量大一些。另外，开启归档后，需要用 RMAN 等方法定期清理归档日志。

   ```sql
   SHOW PARAMETER db_recovery_file_dest;

   ```
 3. 根据业务需求，更改归档日志的配额。

   ```sql
   ALTER SYSTEM SET db_recovery_file_dest_size =50G SCOPE = BOTH;

   ```

### 在源端 Oracle 数据库开启补偿日志

LogMiner Reader 支持 Oracle 系统配置仅开启表级别的补偿日志。如果在迁移过程中，源端 Oracle 数据库新创建了表并需要迁移，则您需要在执行 DML 操作前，打开 PK、UK 的补偿日志。否则，OMS 会报日志不全的异常。

#### 注意

补偿日志需要在 Oracle 主库开启。

对于源端和目标端索引不一致、ETL 不符合预期和分区表迁移性能降低等问题，您需要添加以下补偿日志：

- 添加 DataBase 级别或 Table 级别的 `supplemental_log_data_pk` 和 `supplemental_log_data_ui`。
 - 添加具体列到补偿日志

     - 添加源端和目标端中所有 PK 和 UK 涉及的列。解决源端和目标端索引不一致的问题。
     - 如果有 ETL，请添加 ETL 的列。解决 ETL 不符合预期的问题。
     - 如果目标端是分区表，请添加分区列。解决无法进行分区裁剪，导致降低写入性能的问题。

  您可以执行下述语句，检查添加结果。

  ```sql
  SELECT log_group_type FROM all_log_groups WHERE OWNER = '<schema_name>' AND table_name = '<table_name>';

  ```

  查询结果中包含 ALL COLUMN LOGGING，则检查通过。如果未包含，请查看 `ALL_LOG_GROUP_COLUMNS` 表中，是否包含上述并集的所有列。

  添加具体列至补偿日志的方式，示例如下：

  ```sql
  ALTER TABLE <table_name> ADD SUPPLEMENTAL LOG GROUP <table_name_group> (c1, c2) ALWAYS;

  ```

下表为数据迁移项目在运行过程中，如果进行 DDL 操作，可能会遇到的风险及解决方式。

| 操作 | 风险 | 解决方式 |
| --- | --- | --- |
| CREATE TABLE（且该表需要同步） | 如果该表存在目标端是分区表，源和目标端的索引不一致，需要进行 ETL 等情况，可能影响数据迁移性能，导致 ETL 不符合预期。 | 必须开启 DataBase 级别的 PK、UK 补偿日志。 手动添加涉及的列至补偿日志。 |
| 增加、删除和修改 PK/UK/分区列，或修改 ETL 列 | 会不满足启动时要求添加补偿日志的规则，可能导致数据不一致或数据迁移性能降低的问题。 | 根据上述补偿日志的规则进行相应的添加。 |

LogMiner Reader 根据以下两种方式进行检查。如果检查到补偿日志未打开，则退出。

- DataBase 级别打开 `supplemental_log_data_pk` 和 `supplemental_log_data_ui`。

  执行下述命令，检查是否已打开补偿日志。如果查询结果均为 `YES`，表示已打开补偿日志。

  ```sql
  SELECT supplemental_log_data_pk, supplemental_log_data_ui FROM v$database;

  ```

  如果未打开，请执行下述操作：

     1. 执行下述语句，打开补偿日志。

       ```sql
       ALTER DATABASE ADD supplemental log DATA(PRIMARY KEY, UNIQUE) columns;

       ```
     2. 打开后，切换 2 次归档日志，并且启动项目前需要等待 5 分钟以上。如果是 Oracle RAC，多个实例交替切换。

       ```sql
       ALTER SYSTEM SWITCH LOGFILE;

       ```

       开启补偿日志后，需要切换 2 次归档日志的原因：

       Store 组件定位起始拉取文件时，会根据指定的时间戳回退 0~2 个归档文件。开启补偿后，为了不拉取开启补偿日志前的日志，您需要切换 2 次归档。否则 Store 将异常退出。

       如果是 Oracle RAC，需要多个实例交替切换的原因：

       Oracle RAC 的情况下，如果一个实例切换多次后，再切换另外的实例，而非交替切换，则定位起始拉取文件时，后切换的实例将可能定位至开启补偿日志前的日志。
 - Table 级别打开 `supplemental_log_data_pk` 和 `supplemental_log_data_ui`。

     1. 执行下述语句，确认 DataBase 级别的 `supplemental_log_data_min` 是否打开。

       ```sql
       SELECT supplemental_log_data_min FROM v$database;

       ```

       查询结果为 `YES` 或 `IMPLICIT`，表示已打开。
     2. 执行下述语句，确认待同步表的表级别补偿日志是否打开。

       ```

       每种补偿日志返回一行，结果中需要包含 `ALL COLUMN LOGGING`，或者 `PRIMARY KEY LOGGING` 和 `UNIQUE KEY LOGGING` 都包含。

       如果未打开表级别的补偿日志，请执行下述语句。

       ```sql
       ALTER TABLE table_name ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE) COLUMNS;

       ```
     3. 打开后，切换 2 次归档日志，并且启动项目前需要等待 5 分钟以上。如果是 Oracle RAC，多个实例交替切换。

       ```

### 设置 Oracle 数据库的系统参数（可选）

建议您设置 Oracle 数据库的系统参数 `_log_parallelism_max` 为 1，通常该系统参数默认为 2。

1. 查询 `_log_parallelism_max` 的值。您可以通过以下两种方式进行查询：

      - 方式一

       ```sql
       SELECT NAM.KSPPINM,VAL.KSPPSTVL,NAM.KSPPDESC FROM SYS.X$KSPPI NAM,SYS.X$KSPPSV VAL WHERE NAM.INDX= VAL.INDX AND NAM.KSPPINM LIKE '_%' AND UPPER(NAM.KSPPINM) LIKE '%LOG_PARALLEL%';

       ```
      - 方式二

       ```sql
       SELECT VALUE FROM v$parameter WHERE name = '_log_parallelism_max';

       ```
 2. 修改 `_log_parallelism_max` 的值。进行修改时，分为以下两种情况：

      - Oracle RAC 修改

       ```sql
       ALTER SYSTEM SET "_log_parallelism_max" = 1 SID = '*' SCOPE = spfile;

       ```
      - 非 Oracle RAC 修改

       ```sql
       ALTER SYSTEM SET "_log_parallelism_max" = 1 SCOPE = spfile;

       ```

   Oracle 数据库 10G 版本修改 `_log_parallelism_max` 参数时，如果报错 `write to SPFILE requested but no SPFILE specified at startup`，请执行下述操作：

   ```sql
   CREATE SPFILE FROM PFILE;
   SHUTDOWN IMMEDIATE;
   STARTUP;
   SHOW PARAMETER SPFILE;

   ```
 3. 修改系统参数 `_log_parallelism_max` 后，请重启实例，切换 2 次归档日志，并且启动项目前需要等待 5 分钟以上。

## 操作步骤

1. 新建数据迁移项目。

      1. 登录 OMS 控制台。
      2. 在左侧导航栏，单击 **数据迁移**。
      3. 在 **数据迁移** 页面，单击右上角的 **新建迁移项目**。
 2. 在 **选择源和目标** 页面，配置各项参数。

   | 参数 | 描述 |
   | --- | --- |
   | 迁移项目名称 | 建议使用中文、数字和字母的组合。名称中不能包含空格，长度不能超过 64 个字符。 |
   | 标签 | 单击文本框，在下拉列表中选择目标标签。您也可以单击 **管理标签**，进行新建、修改和删除。详情请参见 [通过标签管理数据迁移项目](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091488)。 |
   | 源端 | 如果您已创建 Oracle 数据源，请从下拉列表中进行选择。如果未创建，请单击下拉列表中的 **新建数据源**，在右侧对话框进行新建。参数详情请参见 [新建 Oracle 数据源](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091476)。 |
   | 目标端 | 如果您已创建 OceanBase 数据库 Oracle 租户数据源，请从下拉列表中进行选择。如果未创建，请单击下拉列表中的 **新建数据源**，在右侧对话框进行新建。参数详情请参见 [新建 OceanBase 物理数据源](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091584)。 |
 3. 单击 **下一步**，在 **选择迁移类型** 页面，配置各项参数。

   **迁移类型** 包括 **结构迁移**、**全量迁移**、**增量同步**、**全量校验** 和 **反向增量**。

   | 迁移类型 | 描述 |
   | --- | --- |
   | 结构迁移 | 负责迁移源库中的数据对象定义（表、索引、约束、注释和视图等）至目标库中，会自动过滤临时表。 |
   | 全量迁移 | 如果选择 **全量迁移**，建议您在迁移数据前，使用 `GATHER_SCHEMA_STATS` 或 `GATHER_TABLE_STATS` 语句收集 Oracle 数据库的统计信息。 |
   | 增量同步 | **增量同步** 包括 [同步 DML](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091478) 和 [同步 DDL](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091486)，您可以根据需求进行选择。同步 DDL 的详情请参见 [Oracle 数据库至 OceanBase 数据库 Oracle 租户的同步 DDL](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091589)。**增量同步** 的使用限制如下：    - 如果您选择了 **同步 DDL**，当源端数据库发生 OMS 未支持的同步 DDL 操作时，会存在数据迁移中断的风险。   - 如果 DDL 操作为新增列，建议您设置该列的属性为 Null，新增列时带有默认值会存在数据迁移中断的风险。       如果必须设置默认值，您可以通过先新增列，再设置默认值的方式绕过。   - 源端 Oracle 数据库暂不支持使用 `empty_clob()` 函数的表进行增量同步。 |
   | 全量校验 | - 如果选择 **全量校验**，建议您在全量校验开始前，分别收集 Oracle 数据库和 OceanBase 数据库 Oracle 租户的统计信息。OceanBase 数据库 Oracle 租户的收集详情请参见 [手动收集统计信息](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000036214)。   - 如果您选择了 **增量同步**，但 **同步 DML** 选项中未选择所有的 DML，则 OMS 不支持本场景下的全量数据校验。 |
   | 反向增量 | 如果迁移表中无主键、无唯一索引且该表的变更量较大，会导致反向增量耗时较长。此时，您可以在源端数据库中添加唯一索引。   以下情况均不支持选择 **反向增量**：    - 存在多表汇聚的情况。   - 存在 Schema 多到一映射的情况。 |
 4. （可选）单击 **下一步**。如果您选择了 **反向增量**，且目标端 OceanBase 数据库 Oracle 租户数据源未配置 Configurl、用户名和密码，则会弹出 **数据源补充信息** 对话框，提醒您配置相应参数。参数详情请参见 [新建 OceanBase 物理数据源](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091584)。

   补充完成后，单击 **测试连通性**。测试连接成功后，单击 **保存**。
 5. 单击 **下一步**，在 **选择迁移对象** 页面，选择迁移对象和迁移范围。

   您可以通过 **指定对象** 和 **匹配规则** 两个入口选择迁移对象。

      - 选择 **指定对象**，在左侧选中需要迁移的对象，单击 **>**，将其添加至右侧列表中。您可以选择一个或多个库的表、视图作为迁移对象。

       #### 注意

            - 待迁移的表名和其中的列名不能包含中文字符。
            - 当数据库的库名或表名存在"$$"字符时，会影响数据迁移项目的创建。
            - 通过 **指定对象** 的方式选择迁移对象后，DDL 操作仅对已选择的对象生效，不支持创建新表。  

       迁移 Oracle 数据库的数据至 OceanBase 数据库 Oracle 租户时，OMS 支持通过文本导入对象、重命名对象名称、设置行过滤、查看列信息，以及移除单个或全部迁移对象。

       | 操作 | 步骤 |
       | --- | --- |
       | 导入对象 | 1. 在 **选择迁移范围** 区域的右侧列表中，单击右上角的 **导入对象**。     2. 在对话框中，单击 **确定**。          **注意：** 导入会覆盖之前的操作选择，请谨慎操作。     3. 在 **导入迁移对象** 对话框中，导入需要迁移的对象。          您可以通过导入 CSV 文件的方式进行库表重命名、设置行过滤条件等操作。详情请参见 [下载和导入迁移对象配置](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091494)。     4. 单击 **检验合法性**。     5. 通过合法性的检验后，单击 **确定**。 |
       | 重命名 | OMS 支持重命名迁移对象的名称，详情请参见 [数据库库表重命名](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091483)。 |
       | 设置 | OMS 支持 `WHERE` 条件实现行过滤，详情请参见 [SQL 条件过滤数据](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091482)。   您还可以在 **查看列** 区域，查看迁移对象的列信息。 |
       | 移除/全部移除 | OMS 支持在数据映射时，对暂时选中到目标端的单个或多个对象进行移除操作。      - 移除单个迁移对象          在 **选择迁移范围** 区域的右侧列表中，鼠标悬停至目标对象，单击显示的 **移除**，即可移除该迁移对象。     - 移除全部迁移对象          在 **选择迁移范围** 区域的右侧列表中，单击右上角的 **全部移除**。在对话框中，单击 **确定**，即可移除全部迁移对象。 |

       当 Oracle 数据库作为源端进行行过滤时，如果针对的是非 PK 或 UK，请开启对应列的补偿日志，或开启 ALL 级别的补偿日志。

       开启对应列的补偿日志的方式如下：

       ```sql
       ALTER TABLE table_name ADD SUPPLEMENTAL LOG GROUP log_group_name (column1, column2, column3) ALWAYS;

       ```

       开启 ALL 级别的补偿日志的方式如下：

       ```sql
       --方式一：开启 DataBase 级别
       ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;
       --方式二：开启 Table 级别
       ALTER TABLE table_name ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;

       ```
      - 选择 **匹配规则** ，详情请参见 [配置迁移对象的匹配规则](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091485)。
 6. 单击 **下一步**，在 **迁移选项** 页面，配置各项参数。

   | 参数 | 描述 |
   | --- | --- |
   | 增量同步起始位点 | - 如果选择迁移类型时已选择 **全量迁移**，该参数不显示。   - 如果选择迁移类型时未选择 **全量迁移**，但选择了 **增量同步**，请在此处指定迁移某个时间节点之后的数据，默认为当前系统时间。详情请参见 [设置增量同步位点](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091480)。 |
   | 全量迁移并发速度 | 包括 **平稳**、**正常** 和 **快速**。全量迁移的性能不同，全量迁移任务所需要的资源也不同。    您也可以通过修改具体 Full-Import 组件的配置，实现自定义并发参数。    **注意**：    在 **选择迁移类型** 页面选中 **全量迁移**，才支持设置该选项。 |
   | 全量校验并发速度 | 包括 **平稳**、**正常** 和 **快速**。不同档位对源端和目标端的资源消耗不同。   您也可以通过修改具体 Full-Verification 组件的配置，实现自定义并发参数。 |
   | 增量记录保存时间 | OMS 中增量解析文件缓存的时长。配置的保存时间越长，OMS Store 组件需要消耗的磁盘空间越大。 |
   | 目标端表对象存在记录时处理策略 | 在 **选择迁移类型** 页面，选中 **全量迁移**，才会显示该参数。处理策略包括 **忽略** 和 **停止迁移**：    - 选择 **忽略**，可能导致源端和目标端的数据不一致。   - 选择 **停止迁移**，当系统检测到目标端表对象存在记录时，该项目将被置为失败状态。如果您需要继续进行数据迁移，请手动恢复该项目。 |
   | 字符编码与长度定义选项 | 已选择 **结构迁移**，且源端和目标端的字符集不一致时，才会显示该参数。   **说明**   - 源端和目标端的字符集不一致（例如，源端为 GBK，目标端为 UTF-8）时，可能会发生字段截断，数据不一致的情况。   - 当您选择 **自动放大目标端字段长度，即 N BYTE → 1.5N BYTE** 时，如果转化后的长度超过最大长度限制，则转化后的长度为最大长度限制。 |
   | 是否允许索引后置 | 您可以设置是否允许全量数据迁移完成后再创建索引，索引后置功能能够缩短全量迁移耗时。选择索引后置的注意事项，请参见表格下方的说明。   **注意**：    - 在 **选择迁移类型** 页面同时选中 **结构迁移** 和 **全量迁移**，才支持设置该选项。   - 仅非唯一键索引支持后置创建。   - OceanBase 数据库 1.x 版本不支持索引后置功能。 |

   允许索引后置的情况下，建议您根据 OceanBase 数据库的硬件条件和当前业务流量情况，自行调节参数。

      - 如果您使用的是 OceanBase 数据库 4.x 版本，请通过黑屏客户端工具调整以下 sys 租户参数和业务租户参数。

            - 调整 sys 租户参数

             ```sql
             // parallel_servers_target 用于设置每个 Server 上的并行查询排队条件。
             // 如果完全为了性能，建议您将该参数调整为大于物理 CPU 的值，例如 1.5 倍。同时设置的值不超过 64，避免产生 OceanBase 数据库内核抢锁问题。
             set global parallel_servers_target = 64;

             ```
            - 调整业务租户参数

             ```sql
             // 文件内存缓冲区限制
             alter system set _temporary_file_io_area_size = '10' tenant = 'xxx';
             // 4.x 关闭限流
             alter system set sys_bkgd_net_percentage = 100;  

             ```
      - 如果您使用的是 OceanBase 数据库 2.x 或 3.x 版本，请通过黑屏客户端工具调整以下 sys 租户参数。

       ```sql
       // parallel_servers_target 用于设置每个 Server 上的并行查询排队条件。
       // 如果完全为了性能，建议您将该参数调整为大于物理 CPU 的值，例如 1.5 倍。同时设置的值不超过 64，避免产生 OceanBase 数据库内核抢锁问题。
       set global parallel_servers_target = 64;
       // data_copy_concurrency 用于设置系统中并发执行的数据迁移复制任务的最大并发数。
       alter system set data_copy_concurrency = 200;

       ```
 7. 单击 **预检查**，系统对数据迁移项目进行预检查。

   在 **预检查** 环节，OMS 会检查数据库用户的读写权限、数据库的网络连接等是否符合要求。全部检查项目均通过后才能启动数据迁移项目。如果预检查报错：

      - 您可以排查并处理问题后，重新执行预检查，直至预检查成功。
      - 您也可以单击失败预检查项操作列中的 **跳过**，会弹出对话框提示您跳过本操作的具体影响，确认可以跳过后，请单击对话框中的 **确定**。
 8. 单击 **启动项目**。如果您暂时无需启动项目，请单击 **保存**，跳转至数据迁移项目的详情页面，您可以根据需要进行手动启动。

   OMS 支持在数据迁移项目运行过程中修改迁移对象，详情请参见 [查看和修改迁移对象](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091491)。数据迁移项目启动后，会根据选择的迁移类型依次执行，详情请参见 [查看数据迁移项目的详情](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000000091492) 中《查看迁移详情》模块的内容。

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
