Oracle索引组织表与大对象平滑迁移至OceanBase的实施方案

本文主要是介绍Oracle索引组织表与大对象平滑迁移至OceanBase的实施方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者简介:严军(花名吉远),十年以上专注于数据库存储领域,精通Oracle、Mysql、OceanBase,对大数据、分布式、高并发、高性能、高可用有丰富的经验。主导过蚂蚁集团核心系统数据库升级,数据库LDC单元化多活项目,常年负责蚂蚁重大数据库活动(如双11、双12、春节红包大促),现任阿里云数据库架构师和云计算专家,专注于金融行业数据库架构设计和咨询工作。

因最近笔者在协助金融客户完成系统的平滑迁移与升级工作。随着迁移系统数量的不断增加,发现客户对Oracle的使用的复杂度和深度都相当高。因此,本文列举了Oracle的索引组织表、大对象的特性,以及迁移到OceanBase(简称OB)的相应方案,以供参考。希望能对大家有所帮助。

1、索引组织表(Index-Organized Table, IOT)

1.1 索引组织表介绍

   索引组织表是一类特殊的表,它将索引和表的数据存储在一起(或者说实际上将所有数据都放入了索引中)。普通表的数据以无序(Heap)的方式存放在数据库中。而索引组织表按照主键进行排序,以二叉树的形式对表的数据进行存储。

●索引组织表不存储ROWID,它通过主键来访问数据。

●索引组织表适合通过主键对数据进行访问的应用。

优点

1.快速的随机访问。索引和表的数据存储在一起,如果对表进行更新,Oracle只更新索引结构。

2.快速的范围扫描。索引组织表已经按照主键对数据进行排序,因此,范围扫描的速度是很快的。

3.更少的存储需求。索引数据和表的数据存储在一起,可以减少存储需求。普通的索引条目只包含索引值和指向数据行的ROWID

组成

1.索引部分。存放主键值,频繁访问的部分非主键值,指向溢出区的ROWID

2.溢出部分。用于存放非主键值。溢出区存放在一个溢出表空间中。用户可以指定溢出表空间。

1.2 问题业务场景

客户反馈OMS迁移时部分SYS_IOT开头的表迁移出现报错,原来以为是系统表,但核对时发现通过 user_objects查询能查到这个表。

最后确定这类表其实都是索引组织表的子表,且子表不支持任何操作。复现脚本如下:

-- 创建IOT时,必须要设定主键,否则报错。
CREATE TABLE TEST_IOT
(id NUMBER PRIMARY KEY,
C1 VARCHAR2(50),
C2 VARCHAR2(10))
ORGANIZATION INDEX PCTTHRESHOLD  10 OVERFLOW;select object_name,object_type from user_objects where object_name like '%IOT%';
/* 
SYS_IOT_OVER_96983	TABLE
SYS_IOT_TOP_96983	INDEX
TEST_IOT	TABLE 
*/-- 只需要对父表进行赋权和获取DDL操作,子表不支持任何操作。
grant select on SYS_IOT_OVER_96983 to scott;
-- ORA-25191: cannot reference overflow table of an index-organized table
select dbms_metadata.get_ddl('TABLE','SYS_IOT_OVER_96983','APPTEST') from dual;
/* ORA-31603: object "SYS_IOT_OVER_96983" of type TABLE not found in schema "APPTEST"
ORA-06512: at "SYS.DBMS_METADATA", line 6478
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 105
ORA-06512: at "SYS.DBMS_METADATA", line 6465
ORA-06512: at "SYS.DBMS_METADATA", line 9202
ORA-06512: at line 1
*/--  查询父子表对应关系
select TABLE_NAME,IOT_NAME from dba_tables where owner='APPTEST';
TEST_IOT	
SYS_IOT_OVER_96983	TEST_IOT

1.3 迁移方案

●表结构迁移:通过dbcat进行结构迁移,索引组织表会被转换成普通表(后续OMS会支持);

●数据迁移:由于Logminer捕获不到增量日志,这类表只能离线迁移。离线迁移方案建议:

   ○主键单字段场景:OMS效率尚可,也可以使用dataX或者导出CSV文件后导入OB的方式;

   ○主键多字段场景:不建议使用OMS,建议datax或者导出方式。

2. 大对象(LOB类型)

2.1 大对象介绍

Oracle

Oracle包含4种大对象类型BLOB、CLOB、NCLOB、BFILE,存储长度都为4G。具体如下:

●CLOB:内部字符大对象,存储单字节和多字节字符数据。支持固定宽度和可变宽度的字符集,常用于大文本的存储。

●NCLOB:国家语言字符集大对象,存储UNICODE类型的数据,支持固定宽度和可变宽度的字符集。

●BLOB:内部二进制大对象,存储非结构化的二进制数据大对象,它可以被认为是没有字符集语义的比特流,一般是图像、声音、视频等文件。

●BFILE:外部二进制文件,存储在数据库外的系统文件,只读的,数据库会将该文件当二进制文件处理。

OB

LOB 全称为大对象数据类型(Large Object),包括 BLOB 和 CLOB,用来存储大型和非结构化数据,例如文本、图像、视频和空间数据等。本文主要提供 OceanBase 数据库当前版本所支持的大对象数据类型的概览和使用限制。

大对象数据类型概览

OceanBase 数据库当前版本所支持的大对象数据类型的信息如下表所示。

类型长度定义长度上限(字符)字符集
BLOB变长48 MBBINARY
CLOB变长48 MB与租户的字符集一致

说明:与 Oracle 通过 LOB Locator 引用数据不同,在 OceanBase 数据库中,LOB Locator 与数据保存在同一结构中。

2.2 迁移方案

●BLOB/CLOB:确定在OB支持的最大长度范围内,平迁。超出最大范围需要业务改造;

●NCLOB:OB不支持 nclob,OMS在迁移中会将字段类型转成 nvarchar2 。注意nvarchar2 上限为 32767 个字节;

●BFILE:建议在Oracle中使用代码转成BLOB后迁移,案例如下:

-- BFile实际上是Oracle数据库指向操作系统文件的一个指针。
-- 读取操作系统文件并转为BLOB代码:-- 创建测试文件
touch /home/oracle/test.jpg
-- 创建directory对象
create directory obtest as '/home/oracle/xxx';
grant read on directory obtest to <username>;
create table obfiletest(col1 bfile,cole2 blob);
INSERT INTO obfiletest(col1) VALUES (BFILENAME ('obtest', 'test.jpg'));-- BFILE转BLOB
Declarev_bfile Bfile;v_blob  Blob;v_dest  Number := 1;v_lang  Number := 1;
Beginv_bfile := bfilename('OBTEST', 'test.jpg');--dbms_output.put_line(v_bfile);dbms_lob.createtemporary(v_blob, True);dbms_lob.fileopen(v_bfile, dbms_lob.file_readonly);dbms_output.put_line(dbms_lob.getlength(v_bfile));dbms_lob.loadblobfromfile(dest_lob => v_blob, src_bfile => v_bfile,amount => dbms_lob.getlength(v_bfile),dest_offset => v_dest, src_offset => v_lang);Update obfiletest Set cole2 = v_blob;dbms_lob.fileclose(file_loc => v_bfile);
End;
/

2.3 关于CLOB字段的UNIQUE INDEX

●在创建CLOB字段的同时,Oracle会自动创建一个UNIQUE INDEX;OB支持CLOB字段类型,但不会自动创建UNIQUE INDEX(手工创建会报错)

●方案:OB不支持该index,直迁数据即可(OMS迁移会忽略)。在做对象校验时需要忽略这类index。

create table test001 (uinfo clob
);
insert into test001 values ('
{"employees":[{"firstName":"Bill","lastName":"Gates","creation_time":"2021-01-01","age":"30"},{"firstName":"George","lastName":"Bush","creation_time":"2021-06-01","age":"26"},{"firstName":"Thomas","lastName":"Carter","creation_time":"2020-03-01","age":"23"}]
}           
');
commit;select * from dba_indexes where table_name='TEST001';SELECT INDEX_NAME,TABLE_NAME,TABLE_OWNER,DBMS_METADATA.get_ddl('INDEX',INDEX_NAME,'APPTEST') INDEX_DDLFROM user_indexes --当前用户下的索引WHERE table_name = 'TEST001';-- 对应DDLCREATE UNIQUE INDEX "APPTEST"."SYS_IL0000101865C00001$$" ON "APPTEST"."TEST001" (PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)TABLESPACE "USERS" PARALLEL (DEGREE 0 INSTANCES 0) 

1699495940

这篇关于Oracle索引组织表与大对象平滑迁移至OceanBase的实施方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/951047

相关文章

Java中对象的创建和销毁过程详析

《Java中对象的创建和销毁过程详析》:本文主要介绍Java中对象的创建和销毁过程,对象的创建过程包括类加载检查、内存分配、初始化零值内存、设置对象头和执行init方法,对象的销毁过程由垃圾回收机... 目录前言对象的创建过程1. 类加载检查2China编程. 分配内存3. 初始化零值4. 设置对象头5. 执行

oracle DBMS_SQL.PARSE的使用方法和示例

《oracleDBMS_SQL.PARSE的使用方法和示例》DBMS_SQL是Oracle数据库中的一个强大包,用于动态构建和执行SQL语句,DBMS_SQL.PARSE过程解析SQL语句或PL/S... 目录语法示例注意事项DBMS_SQL 是 oracle 数据库中的一个强大包,它允许动态地构建和执行

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

PLsql Oracle 下载安装图文过程详解

《PLsqlOracle下载安装图文过程详解》PL/SQLDeveloper是一款用于开发Oracle数据库的集成开发环境,可以通过官网下载安装配置,并通过配置tnsnames.ora文件及环境变... 目录一、PL/SQL Developer 简介二、PL/SQL Developer 安装及配置详解1.下

SQL Server数据库迁移到MySQL的完整指南

《SQLServer数据库迁移到MySQL的完整指南》在企业应用开发中,数据库迁移是一个常见的需求,随着业务的发展,企业可能会从SQLServer转向MySQL,原因可能是成本、性能、跨平台兼容性等... 目录一、迁移前的准备工作1.1 确定迁移范围1.2 评估兼容性1.3 备份数据二、迁移工具的选择2.1

在Rust中要用Struct和Enum组织数据的原因解析

《在Rust中要用Struct和Enum组织数据的原因解析》在Rust中,Struct和Enum是组织数据的核心工具,Struct用于将相关字段封装为单一实体,便于管理和扩展,Enum用于明确定义所有... 目录为什么在Rust中要用Struct和Enum组织数据?一、使用struct组织数据:将相关字段绑

oracle如何连接登陆SYS账号

《oracle如何连接登陆SYS账号》在Navicat12中连接Oracle11g的SYS用户时,如果设置了新密码但连接失败,可能是因为需要以SYSDBA或SYSOPER角色连接,解决方法是确保在连接... 目录oracle连接登陆NmOtMSYS账号工具问题解决SYS用户总结oracle连接登陆SYS账号

Oracle数据库如何切换登录用户(system和sys)

《Oracle数据库如何切换登录用户(system和sys)》文章介绍了如何使用SQL*Plus工具登录Oracle数据库的system用户,包括打开登录入口、输入用户名和口令、以及切换到sys用户的... 目录打开登录入口登录system用户总结打开登录入口win+R打开运行对话框,输php入:sqlp

Java实现Elasticsearch查询当前索引全部数据的完整代码

《Java实现Elasticsearch查询当前索引全部数据的完整代码》:本文主要介绍如何在Java中实现查询Elasticsearch索引中指定条件下的全部数据,通过设置滚动查询参数(scrol... 目录需求背景通常情况Java 实现查询 Elasticsearch 全部数据写在最后需求背景通常情况下

查询Oracle数据库表是否被锁的实现方式

《查询Oracle数据库表是否被锁的实现方式》本文介绍了查询Oracle数据库表是否被锁的方法,包括查询锁表的会话、人员信息,根据object_id查询表名,以及根据会话ID查询和停止本地进程,同时,... 目录查询oracle数据库表是否被锁1、查询锁表的会话、人员等信息2、根据 object_id查询被