---
title: "数据迁移服务隐藏列机制说明 | OceanBase 文档中心"
description: 数据迁移服务隐藏列机制说明 OceanBase 迁移服务（OceanBase Migration Service，OMS）进行结构迁移或同步增量 CREATE TABLE DDL 时，会根据数据迁移项目的实际情况，提供相应的机制。 背景信息 如果您在运行数据迁移项目时，没有进入正向切换步骤，请根据本文不同数据迁移项目…
---
切换语言

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

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

# 数据迁移服务隐藏列机制说明

更新时间：2026-04-14 15:35:47

OceanBase 迁移服务（OceanBase Migration Service，OMS）进行结构迁移或同步增量 `CREATE TABLE` DDL 时，会根据数据迁移项目的实际情况，提供相应的机制。

## 背景信息

如果您在运行数据迁移项目时，没有进入正向切换步骤，请根据本文不同数据迁移项目的操作，自行删除隐藏列和唯一索引。

如果您在运行数据迁移项目时，进入了正向切换步骤，OMS 会根据数据迁移项目的类型，自动删除隐藏列和唯一索引：

- 迁移 Oracle 数据库的数据至 OceanBase 数据库 Oracle 租户时，OMS 将在目标端为全部表对象增加隐藏列，并基于隐藏列创建唯一索引，对应的列和索引将在正向切换步骤被自动移除。创建项目的详情请参见 [迁移 Oracle 数据库的数据至 OceanBase 数据库 Oracle 租户](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-10000000001903080)。

  OMS 会自动添加隐藏列至 CREATE TABLE 语句中，如下所示：

  ```sql
  CREATE TABLE "table1" (
   "S1" NVARCHAR2(2) NOT NULL,
   "S2" NVARCHAR2(20) DEFAULT '默认值字段',
   "OMS_OBJECT_NUMBER" NUMBER INVISIBLE,
   "OMS_RELATIVE_FNO" NUMBER INVISIBLE,
   "OMS_BLOCK_NUMBER" NUMBER INVISIBLE,
   "OMS_ROW_NUMBER" NUMBER INVISIBLE
   );

  ```
 - 下述表格的数据迁移项目为了支持无唯一键表迁移，OMS 将在目标端为对应表添加隐藏列，并基于隐藏列创建唯一索引，对应的列和索引将在正向切换步骤被自动移除。

  | 源端 | 目标端 | 参考文档 |
  | --- | --- | --- |
  | OceanBase 数据库 MySQL 租户 | OceanBase 数据库 MySQL 租户 | [创建 OceanBase 数据库的单向数据迁移项目](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-10000000001904400) |
  | OceanBase 数据库 Oracle 租户 | OceanBase 数据库 Oracle 租户 | [创建 OceanBase 数据库的单向数据迁移项目](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-10000000001904400) |
  | OceanBase 数据库 Oracle 租户 | Oracle 数据库 | [创建 OceanBase 数据库 Oracle 租户至 Oracle 数据库的数据迁移项目](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-10000000001903079) |
  | Oracle 数据库 | OceanBase 数据库 MySQL 租户 | [创建 Oracle 数据库至 OceanBase 数据库 MySQL 租户的数据迁移项目](https://www.oceanbase.com/docs/enterprise-oms-doc-cn-10000000001904397) |

     - OceanBase 数据库 MySQL 租户之间的数据迁移，OMS 会自动添加隐藏列、隐藏列注释和唯一索引至 `CREATE TABLE` 语句中。

      ```sql
      //没有分区字段，创建隐藏列和唯一索引
      create table `table2` (
          `c1` binary(1),
          `OMS_PK_INCRMT` bigint COMMENT 'Reserved for data migration tasks of OMS',
          UNIQUE KEY `UK_table2_OBPK_INCRMT` (`OMS_PK_INCRMT`)
      );
      //有分区字段，创建隐藏列和唯一索引
      create table `partlistcolumns_key_nopri` (
          `col1` int(11),
          `col2` decimal(10,2),
          `col3` decimal(10,2),
          `col4` bit(1),
          `col5` tinyint(4),
          `col6` smallint(6),
          `OMS_PK_INCRMT` bigint COMMENT 'Reserved for data migration tasks of OMS',
          UNIQUE KEY `UK_partlistcolumns_key_nopri_OBPK_INCRMT` (`col1`,`col6`, `OMS_PK_INCRMT`) LOCAL
      )
      default charset=utf8mb4
      default collate=utf8mb4_general_ci
      PARTITION BY LIST COLUMNS (col1)
      SUBPARTITION BY KEY (col6)
      subpartition template (
          SUBPARTITION `p0`,
          SUBPARTITION `p1`,
          SUBPARTITION `p2`,
          SUBPARTITION `p3`
      )
      (
          PARTITION `p1` VALUES IN (1),
          PARTITION `p2` VALUES IN (2),
          PARTITION `p3` VALUES IN (3),
          PARTITION `p4` VALUES IN (4)
      );

      ```
     - OceanBase 数据库 Oracle 租户之间的数据迁移，OMS 会自动添加隐藏列至 `CREATE TABLE` 语句中。

      ```sql
      //Oracle 数据库 12C 以前版本
      CREATE TABLE "table3" (
          "id" NUMBER,
          "status" VARCHAR2(1 BYTE),
          "OMS_PK_INCRMT" NUMBER
      );
      //Oracle 数据库 12C 及以后版本
      CREATE TABLE "table3" (
          "id" NUMBER,
          "status" VARCHAR2(1 BYTE),
          "OMS_PK_INCRMT" NUMBER INVISIBLE
      );

      ```
     - OceanBase 数据库 Oracle 租户至 Oracle 数据库的数据迁移，OMS 会自动添加隐藏列至 `CREATE TABLE` 语句中。

      ```sql
      CREATE TABLE "table4" (
          "V1" CHAR(20 BYTE) DEFAULT 'test',
          "OMS_PK_INCRMT" NUMBER
      );

      ```
     - Oracle 数据库至 OceanBase 数据库 MySQL 租户的数据迁移，OMS 会自动添加隐藏列和隐藏列注释至 `CREATE TABLE` 语句中。

      ```sql
      CREATE TABLE "table5" (
          "V1" CHAR(20) BINARY DEFAULT 'test',
          `OMS_OBJECT_NUMBER` BIGINT COMMENT 'Reserved for data migration tasks of OMS',
          `OMS_RELATIVE_FNO` BIGINT COMMENT 'Reserved for data migration tasks of OMS',
          `OMS_BLOCK_NUMBER` BIGINT COMMENT 'Reserved for data migration tasks of OMS',
          `OMS_ROW_NUMBER` BIGINT COMMENT 'Reserved for data migration tasks of OMS',
      UNIQUE KEY `UK_{table}_OMS_ROWID` (
          `OMS_OBJECT_NUMBER`,
          `OMS_RELATIVE_FNO`,
          `OMS_BLOCK_NUMBER`,
          `OMS_ROW_NUMBER`
          )
      );

      ```

## 前置说明

- "{partition_col_0}" 或者 `{partition_col_0}` 为表分区字段，可能存在多个。存在多个时，请使用英文逗号（,）分隔。例如，`"{partition_col_0}", "{partition_col_1}","{partition_col_2}"` 或 `{partition_col_0}`,`{partition_col_1}`,`{partition_col_2}`。
 - {schema}、{table}、{partition_col_0}、{partition_col_1} 分别为库名、表名、分区字段名、分区字段名的占位符。

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

迁移 Oracle 数据库的数据至 OceanBase 数据库 Oracle 租户时，OMS 不区分是否为无主键表，会统一添加隐藏列和唯一索引。

- 添加隐藏列

  ```sql
  ALTER TABLE "{schema}"."{table}" ADD "OMS_OBJECT_NUMBER" NUMBER INVISIBLE;
  ALTER TABLE "{schema}"."{table}" ADD "OMS_RELATIVE_FNO" NUMBER INVISIBLE;
  ALTER TABLE "{schema}"."{table}" ADD "OMS_BLOCK_NUMBER" NUMBER INVISIBLE;
  ALTER TABLE "{schema}"."{table}" ADD "OMS_ROW_NUMBER" NUMBER INVISIBLE;

  ```
 - 添加唯一索引

  ```sql
  // 有分区字段
  CREATE UNIQUE INDEX "{schema}"."UK_{table}_OMS_ROWID" ON "{schema}"."{table}" ("OMS_OBJECT_NUMBER", "OMS_RELATIVE_FNO", "OMS_BLOCK_NUMBER", "OMS_ROW_NUMBER", "{partition_col_0}", "{partition_col_1}") LOCAL;
  // 没有分区字段
  CREATE UNIQUE INDEX "{schema}"."UK_{table}_OMS_ROWID" ON "{schema}"."{table}" ("OMS_OBJECT_NUMBER", "OMS_RELATIVE_FNO", "OMS_BLOCK_NUMBER", "OMS_ROW_NUMBER");

  ```
 - 删除唯一索引

  ```sql
  DROP INDEX "{schema}"."UK_{table}_OMS_ROWID";

  ```
 - 删除隐藏列

  ```sql
  ALTER TABLE "{schema}"."{table}" DROP ("OMS_OBJECT_NUMBER", "OMS_RELATIVE_FNO", "OMS_BLOCK_NUMBER", "OMS_ROW_NUMBER");

  ```

## OceanBase 数据库 MySQL 租户之间的数据迁移

迁移 OceanBase 数据库 MySQL 租户的数据至 OceanBase 数据库 MySQL 租户时，OMS 会对无唯一键表添加列和唯一索引。

#### 注意

容灾双活场景仅支持迁移有唯一键表。

您可以执行下述命令（其中 {schema}、{table} 需要替换为实际的库名和表名），判断是否为无唯一键表。如果无返回结果，即可视为无唯一键表。

```sql
SELECT 1 FROM information_schema.statistics WHERE TABLE_SCHEMA = {schema} AND TABLE_NAME = {table} GROUP BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME HAVING count(1) = count(IF(upper(nullable) != 'YES' and NON_UNIQUE = 0, 1, NULL));

```

- 添加列

  ```sql
  ALTER TABLE `{schema}`.`{table}` ADD COLUMN `OMS_PK_INCRMT` BIGINT;

  ```sql
  // 有分区字段
  CREATE UNIQUE INDEX `UK_{table}_OBPK_INCRMT` ON `{schema}`.`{table}` (`OMS_PK_INCRMT`, `{partition_col_0}`, `{partition_col_1}`) LOCAL;
  // 没有分区字段
  CREATE UNIQUE INDEX `UK_{table}_OBPK_INCRMT` ON `{schema}`.`{table}` (`OMS_PK_INCRMT`);

  ```sql
  DROP INDEX `UK_{table}_OBPK_INCRMT` ON `{schema}`.`{table}`;

  ```
 - 删除列

  ```sql
  ALTER TABLE `{schema}`.`{table}` DROP COLUMN `OMS_PK_INCRMT`;

  ```

## OceanBase 数据库 Oracle 租户之间的数据迁移

迁移 OceanBase 数据库 Oracle 租户的数据至 OceanBase 数据库 Oracle 租户时，OMS 会对无主键表添加隐藏列和唯一索引。

您可以执行下述命令（其中 {schema}、{table} 需要替换为实际的库名和表名），判断是否为无主键表。如果无返回结果，即可视为无主键表。

```sql
SELECT 1 FROM ( SELECT DC.OWNER, DC.TABLE_NAME, DC.CONSTRAINT_NAME FROM ALL_CONS_COLUMNS DCC JOIN ALL_CONSTRAINTS DC ON DCC.CONSTRAINT_NAME = DC.CONSTRAINT_NAME AND DCC.OWNER = DC.OWNER JOIN ALL_TAB_COLUMNS DTC ON DCC.COLUMN_NAME = DTC.COLUMN_NAME AND DCC.OWNER = DTC.OWNER AND DCC.TABLE_NAME = DTC.TABLE_NAME WHERE DCC.OWNER = {schema} AND DCC.TABLE_NAME = {table} AND DC.CONSTRAINT_TYPE IN ('U', 'P') GROUP BY DC.OWNER, DC.TABLE_NAME, DC.CONSTRAINT_NAME HAVING COUNT(*) = COUNT( CASE DTC.NULLABLE WHEN 'Y' THEN NULL ELSE 1 END ) MINUS SELECT TABLE_OWNER, TABLE_NAME, INDEX_NAME FROM ALL_IND_EXPRESSIONS WHERE TABLE_OWNER = {schema} AND TABLE_NAME = {table} );

```

- 添加隐藏列

  ```sql
  ALTER TABLE "{schema}"."{table}" ADD "OMS_PK_INCRMT" NUMBER INVISIBLE;

  ```sql
  // 有分区字段
  CREATE UNIQUE INDEX "{schema}"."UK_{table}_OBPK_INCRMT" ON "{schema}"."{table}"("OMS_PK_INCRMT", "{partition_col_0}", "{partition_col_1}") LOCAL;
  // 没有分区字段
  CREATE UNIQUE INDEX "{schema}"."UK_{table}_OBPK_INCRMT" ON "{schema}"."{table}"("OMS_PK_INCRMT");

  ```sql
  DROP INDEX "{schema}"."UK_{table}_OBPK_INCRMT";

  ```sql
  ALTER TABLE "{schema}"."{table}" DROP COLUMN "OMS_PK_INCRMT";

  ```

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

迁移 OceanBase 数据库 Oracle 租户的数据至 Oracle 数据库时，OMS 会对无主键表添加隐藏列和唯一索引。

```

- 添加隐藏列

  ```sql
  // Oracle 数据库 12C 以下版本
  ALTER TABLE "{schema}"."{table}" ADD "OMS_PK_INCRMT" NUMBER;
  // Oracle 数据库 12C 及以上版本
  ALTER TABLE "{schema}"."{table}" ADD "OMS_PK_INCRMT" NUMBER INVISIBLE;

  ```sql
  // 有分区字段
  CREATE UNIQUE INDEX "{schema}"."{table}" ON "{schema}"."{table}"("OMS_PK_INCRMT", "{partition_col_0}", "{partition_col_1}") LOCAL;
  // 没有分区字段
  CREATE UNIQUE INDEX "{schema}"."{table}" ON "{schema}"."{table}"("OMS_PK_INCRMT");

  ```sql
  DROP INDEX "{schema}"."{table}";

  ```

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

迁移 Oracle 数据库的数据至 OceanBase 数据库 MySQL 租户时，OMS 会对无唯一键表添加列和唯一索引。

```sql
select 1 from ALL_CONS_COLUMNS DCC join ALL_CONSTRAINTS DC ON DCC.CONSTRAINT_NAME = DC.CONSTRAINT_NAME AND DCC.OWNER = DC.OWNER join ALL_TAB_COLUMNS DTC on DCC.COLUMN_NAME = DTC.COLUMN_NAME AND DCC.OWNER = DTC.OWNER AND DCC.TABLE_NAME = DTC.TABLE_NAME where DCC.owner = {schema} AND DCC.TABLE_NAME = {table} and DC.constraint_type in ('U', 'P') group by DC.OWNER, DC.TABLE_NAME, DC.CONSTRAINT_NAME having count(*) = count(CASE DTC.NULLABLE WHEN 'Y' THEN NULL ELSE 1 END);

```

- 添加列

  ```sql
  ALTER TABLE `{schema}`.`{table}` ADD COLUMN `OMS_OBJECT_NUMBER` BIGINT;
  ALTER TABLE `{schema}`.`{table}` ADD COLUMN `OMS_RELATIVE_FNO` BIGINT;
  ALTER TABLE `{schema}`.`{table}` ADD COLUMN `OMS_BLOCK_NUMBER` BIGINT;
  ALTER TABLE `{schema}`.`{table}` ADD COLUMN `OMS_ROW_NUMBER` BIGINT;

  ```sql
  // 有分区字段
  CREATE UNIQUE INDEX `UK_{table}_OMS_ROWID` ON `{schema}`.`{table}` (`OMS_OBJECT_NUMBER`, `OMS_RELATIVE_FNO`, `OMS_BLOCK_NUMBER`, `OMS_ROW_NUMBER`, `{partition_col_0}`, `{partition_col_1}`) LOCAL;
  // 没有分区字段
  CREATE UNIQUE INDEX `UK_{table}_OMS_ROWID` ON `{schema}`.`{table}` (`OMS_OBJECT_NUMBER`, `OMS_RELATIVE_FNO`, `OMS_BLOCK_NUMBER`, `OMS_ROW_NUMBER`);

  ```sql
  DROP INDEX UK_{table}_OMS_ROWID ON {table};

  ```
 - 删除列

  ```sql
  ALTER TABLE `{schema}`.`{table}` DROP COLUMN `OMS_OBJECT_NUMBER`, DROP COLUMN `OMS_RELATIVE_FNO`, DROP COLUMN `OMS_BLOCK_NUMBER`, DROP COLUMN `OMS_ROW_NUMBER`;

  ```

 上一篇 下一篇 ![有帮助](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) 咨询热线
