如何将Oracle 中的部分不兼容对象迁移到 OceanBase

news2024/11/22 16:28:21

本文总结分析了 Oracle 迁移至 OceanBase 时,在出现三种不兼容对象的情况时的处理策略以及迁移前的预检方式,通过提前发现并处理这些问题,可以有效规避迁移过程中的报错风险。

作者:余振兴,爱可生 DBA 团队成员,热衷技术分享、编写技术文档。本文共 1500 字,预计阅读需要 5 分钟。

背景

在推进自研改造的进程中,我们需将Oracle数据库迁移至OceanBase(Oracle模式)数据库。尽管 OceanBase 在 Oracle 兼容性方面已表现出色,但仍旧存在一些特殊语法或对象需要我们进行特别处理。以下是我们在迁移过程中遇到的一些不完全兼容对象及其处理逻辑。

Oracle 中 LOB 类数据迁移到 OB 时的处理逻辑

Oracle 中 CLOB 和 BLOB 类型均可达到 4G 大小(以 Oracle 11.2 为例),而 OceanBase 数据库当前版本(3.2.3.x)所支持的大对象数据类型的信息如下表所示:

类型BLOBCLOB
长度变长变长
自定义长度上限(字符)48MB48MB
字符集BINARY与租户字符集一致

考虑到从 Oracle 迁移到 OceanBase,如果涉及 LOB 类字段,可能会存在当 LOB 数据大于 48M 时数据丢失的问题,需要提前发现这类数据并进行处理。

2.1 找到 Oracle 中 LOB 数据最大长度

我们可以构建一个实验生成 CLOB 及 BLOB 类型数据,使用 Oracle 自带的 DBMS_LOB 包获取对应类型的最大值。

2.1.1 构建包含LOB类型的数据表

CREATE TABLE t_lob(
    c_ID NUMBER,
    c_clob CLOB,
    c_blob BLOB
);

2.1.2 创建造数据存储过程

随机插入 100 条记录到 t_lob 表。

CREATE OR REPLACE PROCEDURE insert_random_lob_data AS
BEGIN
  DECLARE
    l_random_string VARCHAR2(10000);
    l_random_blob BLOB;
  BEGIN
    FOR i IN 1..100 LOOP
      l_random_string := dbms_random.string('U', dbms_random.value(1, 10000));
      dbms_lob.createtemporary(l_random_blob, TRUE);
      dbms_lob.writeappend(l_random_blob, LENGTH(l_random_string), utl_raw.cast_to_raw(l_random_string));
      
      INSERT INTO t_lob(c_ID, c_clob, c_blob)
      VALUES(i, l_random_string, l_random_blob);
      
      dbms_lob.freetemporary(l_random_blob);
    END LOOP;
    COMMIT;
  END;
END;
/

2.1.3 查询该表中 CLOB 和 BLOB 字段的最大值

SELECT MAX(DBMS_LOB.GETLENGTH(C_CLOB)) AS LONGEST_CLOB,
       MAX(DBMS_LOB.GETLENGTH(C_BLOB)) AS LONGEST_BLOB
  FROM T_LOB;

2.2 获取整个数据库中 LOB 字段值较大的清单

排除了系统用户,获取 LOB 字段清单后再基于清单中的 LOB 字段单独分析其最大值。

SELECT COL.OWNER,
       COL.TABLE_NAME,
       COL.COLUMN_NAME,
       COL.DATA_TYPE,
       COL.AVG_COL_LEN,
       COL.CHAR_LENGTH,
       TAB.NUM_ROWS
  FROM DBA_TABLES TAB, DBA_TAB_COLUMNS COL
 WHERE TAB.OWNER = COL.OWNER
   AND TAB.TABLE_NAME = COL.TABLE_NAME
   AND COL.DATA_TYPE IN ('CLOB', 'BLOB')
   AND COL.OWNER NOT IN ('SYS', 'SYSTEM')
   AND COL.OWNER IN
       (SELECT USERNAME FROM DBA_USERS WHERE ACCOUNT_STATUS = 'OPEN')
   AND COL.TABLE_NAME NOT LIKE 'BIN%';

Oracle 中 disable 约束在 OMS 迁移过程中的处理逻辑

在对 Oracle 中的约束类非表对象做一致性校验时,发现部分约束在 OMS 迁移完成后丢失了,需要分析其 OMS 丢失的原因。

3.1 问题分析

从 OMS 界面中获取 DDL 的语句可以看到有 2 个 WARN,且类型是 DISCARD,表示 OMS 判断其是 DISABLE 状态的约束,直接选择了舍弃掉。

-- [WARN] [DISCARD] CONSTRAINT "PK_T_PARTKEY_IS_PK" PRIMARY KEY ("CRT_DTTM") DISABLE NOVALIDATE -> [NULL]
-- [WARN] [DISCARD] CHECK ("ACT_ID" IS NOT NULL) DISABLE NOVALIDATE -> [NULL]
CREATE TABLE "T_PARTKEY_IS_PK" (
    "ACT_ID" NUMBER(10,0),
    "SRT_ID" NUMBER(10,0),
    "SRT_ORIGNAL_ID" NUMBER(10,0),
    "CRT_DTTM" DATE,
    "LASTUPT_DTTM" DATE
)

3.2 问题结论

Oracle 侧处于 DISABLE 状态的约束通过 OMS 迁移时会被舍弃,不会在 OB 侧创建,在对约束对象比对时,需要额外注意 Oracle 端约束的 status 是否处于 DISABLE 状态,本身对业务和功能没有影响。

3.3 约束校验时提前排除 DISABLE 的约束

可以通过以下语句观测源端 Oracle 约束状态。

-- 手工将T_PARTKEY_IS_PK表的约束都disable
ALTER TABLE ZHENXING.T_PARTKEY_IS_PK DISABLE NOVALIDATE CONSTRAINT PK_T_PARTKEY_IS_PK;
ALTER TABLE ZHENXING.T_PARTKEY_IS_PK DISABLE CONSTRAINT SYS_C0011109;

SELECT OWNER,
       TABLE_NAME,
       CONSTRAINT_NAME,
       CONSTRAINT_TYPE,
       INDEX_NAME,
       STATUS
  FROM DBA_CONSTRAINTS
 WHERE OWNER = 'ZHENXING'
   AND TABLE_NAME = 'T_PARTKEY_IS_PK';

Oracle 中分区表迁移到 OB 后,带有的自动分区属性丢失

自动分区属性是 Oracle 11g 的特性,可以用 INTERVAL 语法基于天、月、年做自动分区创建。 在通过 OMS 迁移到 OB 后,发现自动分区属性丢失了,会导致当分区未自动创建时导致新增数据没法写入分区表,导致报错。

4.1 问题分析

从 OMS 界面中获取 DDL 的语句可以看到有 1 个 WARN,且类型是 DISCARD,表示 OMS 判断其不完全兼容,直接选择了舍弃掉。

-- OMS 迁移表结构时记录的WARN信息,表示自动分区属性由于不兼容会自动DISCARD舍弃
[WARN] [DISCARD]  INTERVAL (NUMTOYMINTERVAL (1,'MONTH')) -> [NULL]

4.2 问题结论

所以在 Oracle 迁移到 OB 前,需要把 Oracle 端存在自动分区属性的表提前找出,避免由于迁移到 OB 后分区为未自动创建导致的数据无法插入的报错,并且找出这类分区后,先在 Oracle 端创建足够的多分区,避免迁移过程中源端分区数增加导致比对不一致的情况。并记录清单告知业务开发待后续用其他方式定期生成新分区。

4.3 如何找出 Oracle 中自动分区的表

4.3.1 Oracle 侧模拟自动分区

-- 创建基于天的自动分区表
SQL> create table interval_sales (
    prod_id number(6),
    time_id date)
    partition by range (time_id)
    INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
    (partition p1 values less than (to_date('2015-01-01','yyyy-mm-dd')));

-- 查询当前分区,默认生成了1个定义好的分区
SQL> SELECT TABLE_NAME, PARTITION_NAME
  FROM USER_TAB_PARTITIONS
 WHERE TABLE_NAME = 'INTERVAL_SALES';

TABLE_NAME                       PARTITION_NAME
------------------------------ ------------------------------
INTERVAL_SALES                       P1

-- 插入数据(不在默认分区内)
SQL> INSERT INTO INTERVAL_SALES VALUES(001, TO_DATE('2015-02-01', 'yyyy-mm-dd'));

-- 自动生成了新分区
TABLE_NAME                       PARTITION_NAME
------------------------------ ------------------------------
INTERVAL_SALES                       P1
INTERVAL_SALES                       SYS_P221

-- 单独查看该分区数据(验证数据确实存在新分区)
SQL> SELECT * FROM INTERVAL_SALES PARTITION(SYS_P221);

   PROD_ID TIME_ID
---------- ---------
         1 01-FEB-15

4.3.2 统计 Oracle 侧有哪些表是自动分区的表

/*
PARTITION_COUNT: Number of partitions in the table. For interval partitioned tables, the value of this column is always 1048575.
*/
SELECT T1.OWNER,
       T1.TABLE_NAME,
       T1.INTERVAL,
       T1.PARTITIONING_TYPE,
       T1.PARTITION_COUNT,
       T1.SUBPARTITIONING_TYPE      AS SUB_TYPE,
       T1.SUBPARTITIONING_KEY_COUNT SUB_COUNT,
       T1.STATUS
  FROM DBA_PART_TABLES T1
 WHERE 1 = 1
   AND TABLE_NAME NOT LIKE 'BIN%'
   AND (INTERVAL IS NOT NULL OR PARTITION_COUNT = 1048575);

总结

以上总结分析了 3 种 Oracle 对象和 OB 对象不兼容时的处理方法和提前统计发现的操作方式,在迁移前提前发现这类问题能有效避免在迁移过程中报错的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1601193.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【网络编程】如何创建一个自己的并发服务器?

hello !大家好呀! 欢迎大家来到我的网络编程系列之如何创建一个自己的并发服务器,在这篇文章中,你将会学习到在Linux内核中如何创建一个自己的并发服务器,并且我会给出源码进行剖析,以及手绘UML图来帮助大家…

基于Docker构建CI/CD工具链(十)总结

我们用九篇文章简单的介绍了使用Docker构建CICD工具链,希望对你的工作有所帮助。 基于Docker构建CI/CD工具链(一)构建基础工具镜像 基于Docker构建CI/CD工具链(二)快速搭建Gitlab代码库 基于Docker构建CI/CD工具链&…

【DM8】ODBC

官网下载ODBC https://www.unixodbc.org/ 上传到linux系统中 /mnt下 [rootstudy ~]#cd /mnt [rootstudy mnt]# tar -zxvf unixODBC-2.3.12.tar.gz [rootstudy mnt]# cd unixODBC-2.3.12/ [rootstudy unixODBC-2.3.12]# ./configure 注意:若是报以上错 则是gcc未安…

[计算机效率] 网站推荐:格式转换类

4.2 格式转换类 在日常办公和学习中,我们经常需要将不同格式的文件进行转换,特别是PDF文件,因其跨平台、易阅读的特性而备受青睐。然而,PDF文件的编辑和转换往往是一个棘手的问题。今天,我为大家推荐一系列优质的文件…

笔试题2 -- 字符串数组中指定字符串间的最短距离

字符串数组中指定字符串间的最短距离 文章目录 字符串数组中指定字符串间的最短距离题目还原解法一:暴力遍历 (HashVector法)解法二:算法改进 (双指针法)总结 题目链接: 数组中两个字符串的最小距离 – 牛客网 题目还原 给定一个字符串数组s…

速卖通、阿里国际站自养买家账号补单测评核心问题

补单在跨境电商中扮演着重要的角色,卖家们了解到补单可以快速增加产品的销量、评论数量,提升排名,从而打造爆款产品。产品的购买率和评价对于转化率和平台排名至关重要! 当排名不断提高,带来的流量也会增加&#xff0…

机器学习和深度学习--李宏毅(笔记与个人理解)Day17

Day 17Convolutional Neyral Network (CNN) 卷积神经网络一般都用在image 上面比较多一些,所以课程的例子大多数也都是image Image Classification the same size how about for pc? 这里对于tensor 张量这个概念,我还是比较奇怪,在我认为一…

java混淆的公司有哪些

一些提供 Java 混淆服务的公司包括: PreEmptive Solutions:PreEmptive Solutions 提供了一系列用于保护 Java 和 .NET 应用程序的工具,包括混淆、代码压缩、加密和漏洞检测等功能。 DexGuard:DexGuard 是 Guardsquare 公司推出的…

ubuntu磁盘文件损坏不能启动的修复方法

目录 1.错误现象2.解决 1.错误现象 今天早上启动虚拟机中的ubuntu发生如下错误,不能正常启动 2.解决 根据上面的提示可以运行以下命令修复: e2fsck /dev/sda1 #根据提示输入y reboot重启后ubuntu系统正常.

HR面试潜台词_弹性工作不强制考勤=做不完就要加班 扁平管理化=没有升职空间 原则上不鼓励加班=

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7 深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞…

【Leetcode每日一题】 递归 - 二叉树的所有路径(难度⭐)(59)

1. 题目解析 题目链接:257. 二叉树的所有路径 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 针对二叉树路径的求解问题,我们可以采用深度优先遍历(DFS)的策略来寻找所…

【LAMMPS学习】八、基础知识(3.3)使用分布式网格

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语,以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

筑牢个人信息安全防线,海云安受邀参加武汉“名家论坛”国家安全教育日专题讲座

近日,武汉“名家论坛”国家安全教育日专题讲座活动《“刷脸”有风险,如何保护我们的个人信息安全?》在武汉图书馆报告厅举办,海云安副总工程师李博士受邀参加本次活动。 活动以线下讲座、线上直播的形式,结合“普法讲座…

【数据结构1-基本概念和术语】

这里写自定义目录标题 0.数据,数据元素,数据项,数据对项,数据结构,逻辑结构,存储结构1.结构1.1逻辑结构1.2存储结构1.2.1 顺序结构1.2.2链式结构 1.3数据结构1.3.1基本数据类型1.3.2抽象数据类型1.3.2.1一个…

算法学习——LeetCode力扣补充篇9(912. 排序数组、21. 合并两个有序链表、33. 搜索旋转排序数组、103. 二叉树的锯齿形层序遍历)

算法学习——LeetCode力扣补充篇9 912. 排序数组 912. 排序数组 - 力扣(LeetCode) 描述 给你一个整数数组 nums,请你将该数组升序排列。 示例 示例 1: 输入:nums [5,2,3,1] 输出:[1,2,3,5] 示例 2&…

Qt+vstudio2022的报错信息积累

从今天开始记录一下平常开发工作中的报错记录,后续有错误动态补充! 报错信息:【MSB8041】此项目需要 MFC 库。从 Visual Studio 安装程序(单个组件选项卡)为正在使用的任何工具集和体系结构安装它们。 解决: 背景:换…

4个步骤:如何使用 SwiftSoup 和爬虫代理获取网站视频

摘要/导言 在本文中,我们将探讨如何使用 SwiftSoup 库和爬虫代理技术来获取网站上的视频资源。我们将介绍一种简洁、可靠的方法,以及实现这一目标所需的步骤。 背景/引言 随着互联网的迅速发展,爬虫技术在今天的数字世界中扮演着越来越重要…

潮玩宇宙小程序定制大逃杀游戏APP开发H5游戏

游戏名称:潮玩宇宙大逃杀 游戏类型:休闲竞技类小游戏 游戏目标:玩家通过选择房间躲避杀手,生存下来并瓜分被杀房间的元宝。 核心功能 房间选择:玩家进入游戏后,可以选择一间房间躲避杀手。杀手行动&…

十大排序——7.希尔排序

下面我们来看一下希尔排序 目录 1.介绍 2.代码实现 3.总结与思考 1.介绍 希尔排序是插入排序的一种优化,可以理解为是一种分组的插入排序。 希尔排序的要点: 简单来说,就是分组实现插入,每组元素的间隙称为gap,…

文件服务: txt文件预览乱码问题

文章目录 一、背景二、解决方案1、转换流(解决代码与文件编码不一致读取乱码的问题)2、获取文本文件的字符编码 一、背景 在springboot项目中使用springmvc web.resources的形式进行文件访问。本地上传txt文件编码格式为GB2312(中文简体),浏…