当前位置: 首页 > news >正文

OceanBase 中的ROWID与Oracle的差异与如何迁移

1. ROWID

1.1 OB和Oracle中rowid的区别

正如大家所知道的,OceanBase兼容Oracle的rowid特性,但在其生成规则上却存在不同,具体表现如下:

OceanBase

● 定义:OceanBase(简称 OB)的rowid是通过主键(包括隐藏主键)直接经过base64编码计算得出的,因此一旦主键发生变动,相应的rowid也会随之改变。关于主键的生成规则,具体如下:

   ○有主键非分区表,用户定义的主键

   ○有主键分区表,用户定义的主键

   ○无主键非分区表,内部生成sequence作为隐藏主键

   ○无主键分区表,分区键+sequence作为隐藏主键

●长度:17个字符。

Oracle

●定义:该值表明了该行在oracle数据库中的物理具体位置。保存rowid需要10个字节或者是80个位二进制位。这80个二进制位分别是:

   ○1. 数据对象编号,表明此行所属的数据库对象的编号,每个数据对象在数据库建立的时候都被唯一分配一个编号,并且此编号唯一。数据对象编号占用大约32位。

   ○2. 对应文件编号,表明该行所在文件的编号,表空间的每一个文件标号都是唯一的。文件编号所占用的位置是10位。

   ○3. 块编号,表明改行所在文件的块的位置块编号需要22位。

   ○4. 行编号,表明该行在行目录中的具体位置行编号需要16位。

●长度:rowid需要 10个字节的存储空间,并用18个字符来显示。

1.2 用户业务场景和迁移方案

业务场景

●表A:存储业务单据信息,数据量较大;

●表B:A表关联表,表中有一列存放B表的rowid值;

●业务场景需要经常通过B表去A表关联取数,为了优化取数性能直接通过rowid关联。

迁移方案

由于迁移后OB rowid长度和Oracle不一致,且定义完全不同,列数据迁移过去会失去原有意义成为垃圾数据。具体改造方案如下:

  1.表结构调整:删除rowid类型列,数据也不做迁移;

  2.性能调优:创建合适索引,通过其他字段关联查询。由于业务侧预留了业务主键可以关联,实测性能满足客户需求。

1.3 Oracle rowid发生变化的场景

由于OMS迁移过程中全量和增量迁移都和源端oracle的rowid密切关联(无论有主键表还是无主键表),所以我们需要密切关注Oracle源端的rowid变化场景,迁移过程中都要避免。Oracle rowid发生变化的场景如下:

○1. Oracle 行迁移

○2. 另外一些不急于rowmovement会导致rowid修改的动作,比如move和逻辑导出再导入

Oracle 行迁移(row movement)场景

●行迁移 ( Row movement): 默认情况下,oracle数据块中的一行其生命周期内是不会发生移动的,即块的rowid不会发生改变。但是在某些情景下,我们希望行的rowid可以发生变化,这时候我们就需要启动表的row movement特性。

-- 启用row movement特性
Alter table table_name enable row movement;
(1)分区表

当我们允许分区表的分区键是可更新的时候,如果分区键的更新导致当前修改的数据条目需要移动到其他分区,此时就会发生rowid的改变。

create table test_rowid(id number,test_value varchar2(10))
partition by list(test_value)(
partition p1 values('1'),
partition p2 values('2'),
partition p3 values('3'));insert into test_rowid values(1,'1');
insert into test_rowid values(2,'2');
insert into test_rowid values(3,'3');
insert into test_rowid values(4,'1');
commit;select rowid,id,test_value from test_rowid ;
/*ROWID	ID	TEST_VALUE
AAAefAAAHAADJMWAAA	1	1
AAAefAAAHAADJMWAAB	4	1
AAAefBAAHAADJcWAAA	2	2
AAAefCAAHAADJsWAAA	3	3 */update test_rowid set test_value=2 where id=4;
-- ORA-14402: updating partition key column would cause a partition changealter table test_rowid enable row movement;update test_rowid set test_value=2 where id=4;
-- 1 row updated.select rowid,id,test_value from test_rowid ;
/*ROWID	ID	TEST_VALUE
AAAefAAAHAADJMWAAA	1	1
AAAefBAAHAADJcWAAA	2	2
AAAefBAAHAADJcWAAB	4	2
AAAefCAAHAADJsWAAA	3	3 */
id=4的列rowid发生变化。
(2)闪回操作

在闪回操作时,我们同样需要开启表的row movement特性。

alter table test_rowid disable row movement;
-- Table altered.SQL> select current_scn from v$database;
-- 38719199select rowid,id,test_value from test_rowid where test_value=1;
/* ROWID	ID	TEST_VALUE
AAAefAAAHAADJMWAAA	1	1 */ delete from test_rowid where test_value=1;
commit;flashback table test_rowid to scn 38719199;
-- ORA-08189: cannot flashback the table because row movement is not enabledalter table test_rowid enable row movement;
-- Table altered.flashback table test_rowid to scn 38719199;
-- Flashback complete.select rowid,id,test_value from test_rowid where test_value=1;
/* ROWID	ID	TEST_VALUE
AAAefAAAHAADJMWAAC	1	1 */

flashback table原理:oracle flashback table 是通过临时表来实现的。

create table hh(id number);
insert into hh values(1);
commit;alter table hh enable row movement;
select current_scn from v$database;
--  1635103update hh set id = 2;
commit; alter session set tracefile_identifier = 'ee';
alter session set sql_trace=true;
flashback table hh to scn 1635103;
-- Flashback complete.通过查看trace文件,我们可以发现oracle  flashback table 是通过一个临时表sys_temp_fbt来实现的。
trace文件中的部分内容如下:
********************************************************************************
sqlid='dtjmzuugu6ktw'
INSERT /*+ APPEND */ into SYS_TEMP_FBT SELECT /*+ FBTSCAN FULL(S) PARALLEL(S, DEFAULT) */ :1, :2, :3, rowid, SYS_FBT_INSDEL FROM "APPTEST"."HH" as of SCN :4 S
********************************************************************************
sqlid='bytpvbcb8zbb6'
/* Flashback Table */ DELETE /*+ BYPASS_UJVC */ FROM (SELECT /*+ ORDERED USE_NL(S) PARALLEL(S,DEFAULT) PARALLEL(T,DEFAULT) */ S.rowid FROM SYS_TEMP_FBT T, "APPTEST"."HH" S WHERE T.rid = S.rowid and T.action = 'D' and T.object#  = : 1) V
********************************************************************************
sqlid='a3h5cbfc5b6xv'
/* Flashback Table */ INSERT /*+ PARALLEL(S, DEFAULT) PARALLEL(T, DEFAULT) */ INTO "APPTEST"."HH" SELECT /*+ USE_NL(S) ORDERED PARALLEL(S, DEFAULT) PARALLEL(T, DEFAULT) */ S.* FROM SYS_TEMP_FBT T , "APPTEST"."HH" as of SCN :1 S WHERE T.rid = S.rowid and T.action = 'I' and T.object# = :2 由此可见,oracle是通过SYS_TEMP_FBT进行删除操作,而后进行插入操作,
因此行的rowid有可能发生改变。SQL> select * from sys_temp_fbt ;
SCHEMA     OBJECT_NAME             OBJECT# RID                            A
---------- -------------------- ---------- ------------------------------ -
hh       hh                      76906 AAASxqAAGAAAAC0AAA             D
hh       hh                      76906 AAASxqAAGAAAAC0AAA             ISQL> select tname,tabtype from tab;
TNAME                    TABTYPE
------------------------------ -------
HH                     TABLE
SYS_TEMP_FBT       TABLE

drop表Oracle有另外的回收站技术恢复,不需要开ROW MOVEMENT

SQL> ALTER TABLE test_rowid DISABLE ROW MOVEMENT;  
Table altered.  
SQL> DROP TABLE test_rowid;  
Table dropped.  
SQL> FLASHBACK TABLE test_rowid TO BEFORE DROP;  
Flashback complete.  
没错,因为drop表Oracle有另外的回收站技术恢复过来,而删除几行记录是不能 直接通过回收站恢复的。
(3)回收空间

在收缩空间时,也会造成行的移动

SQL> alter table hh disable row movement;
Table altered.SQL> alter table hh shrink space;
alter table hh shrink space
*
ERROR at line 1:
ORA-10636: ROW MOVEMENT is not enabledSQL> alter table hh enable row movement;
Table altered.SQL> alter table hh shrink space;
Table altered.Shrink space操作(without  compact)也会导致所有已经打开的游标失效,因此需要谨慎使用!

1.4 OB rowid变化场景:

对于源端是OB的情况,OMS迁移并不会依赖rowid,通过前面的介绍也可以看到OB rowid的变化是很频繁的,主要变化场景如下:

●有主键非分区表,主键发生变化,rowid变化

●有主键分区表,因为分区键包含在主键内,所以同上

●无主键非分区表,对于一行记录rowid不会变化。

●无主键分区表,分区键发生变化时,rowid变化

相关文章:

OceanBase 中的ROWID与Oracle的差异与如何迁移

1. ROWID 1.1 OB和Oracle中rowid的区别 正如大家所知道的,OceanBase兼容Oracle的rowid特性,但在其生成规则上却存在不同,具体表现如下: OceanBase ● 定义:OceanBase(简称 OB)的rowid是通过…...

秋招后端开发面试题 - JVM运行时数据区

目录 运行时数据区前言面试题JVM 内存区域 / 运行时数据区?说一下 JDK1.6、1.7、1.8 内存区域的变化?为什么使用元空间替代永久代作为方法区的实现?Java 堆的内存分区了解吗?运行时常量池?字符串常量池了解吗&#xff…...

【YOLOv8改进[Backbone]】使用SCINet改进YOLOv8在黑暗环境的目标检测效果

目录 一 SCINet 1 本文方法 ① 权重共享的照明学习 ② 自校准模块 ③ 无监督训练损失 二 使用SCINet助力YOLOv8在黑暗环境的目标检测效果 1 整体修改 2 配置文件 3 训练 其他 一 SCINet 官方论文地址:https://arxiv.org/pdf/2204.10137 官方代码地址&…...

ASE docker related research

ASE 2022 Understanding and Predicting Docker Build Duration: An Empirical Study of Containerized Workflow of OSS Projects 理解和预测 Docker 构建持续时间:OSS 项目容器化工作流程的实证研究 Docker 构建是容器化工作流程的关键组成部分,它…...

maven .lastUpdated文件作用

现象 有时候我在用maven管理项目时会发现有些依赖报错,这时你可以看一下本地仓库中是否有.lastUpdated文件,也许与它有关。 原因 有这个文件就表示依赖下载过程中发生了错误导致依赖没成功下载,可能是网络原因,也有可能是远程…...

gtest的编译与使用

文章目录 gtest的编译与使用概述笔记CMake参数官方文档测试程序测试效果END gtest的编译与使用 概述 gTest是 googletest的缩写,如果直接找gTest项目,是找不到的。 库地址 https://github.com/google/googletest.git 迁出到本地后,切到最新…...

【 npm详解:从入门到精通】

文章目录 npm详解:从入门到精通1. [npm](https://www.npmjs.com/)的安装2. npm的基础用法2.1 初始化项目2.2 安装依赖2.3 卸载依赖2.4 更新依赖 3. npm的高级用法3.1 运行脚本3.2 使用npm scope3.3 使用npm link 4. npm资源5. 使用npm进行依赖树分析和可视化6. npm进…...

【Web后端】实现文件上传

表单必须使用post提交 ,enctype 必须是multipart/form-data在Servlet上填加注解 MultipartConfiglocation :默认情况下将存储文件的目录,默认值为“”。maxFileSize :允许上传文件的最大大小,其值以字节为单位。 默认值为-1L表示无…...

react 逻辑 AND 运算符 ()

在 React 组件中&#xff0c;当你想在条件为 true 时渲染一些 JSX 时&#xff0c;它经常会出现&#xff0c;或者什么都不渲染。使用 &#xff0c;只有在以下情况下才能有条件地呈现复选标记&#xff1a;&&isPackedtrue return (<li className"item">{…...

Redis详解(二)

事务 什么是事务&#xff1f; 事务是一个单独的隔离操作&#xff1a;事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中&#xff0c;不会被其他客户端发送来的命令请求所打断。 事务是一个原子操作&#xff1a;事务中的命令要么全部被执行&#xff0c;要么全部都…...

嵌入式:基于STM32的智能家居照明控制系统

在智能家居系统中&#xff0c;自动照明控制不仅提高了居住舒适度&#xff0c;还有助于节能减排。本教程旨在引导读者通过使用STM32微控制器来开发一个智能照明控制系统。该系统能够根据环境光线自动调整室内照明的亮度&#xff0c;并支持通过简单的用户界面手动控制光线。 一、…...

三种基本排序-冒泡,选择,二分

闲话不多说&#xff0c;直接上代码&#xff0c;简明易懂&#xff0c;条理清晰&#xff0c;交互性强&#xff0c;尽善尽美 码住&#xff0c;建议copy下来&#xff1a; 先上二分法吧&#xff0c;稍复杂点的&#xff0c;代码多一些&#xff0c;用了函数调用 二分排序&#xff1…...

windows查找重复的物理地址

单独查询所有物理&#xff08;mac&#xff09;地址&#xff08;cmd执行&#xff09;&#xff1a;arp -a 查找同一局域网下重复的mac&#xff0c;打开power shell执行以下命令&#xff1a; Get-NetNeighbor | Where-Object { $_.State -eq "Reachable" } | Select-O…...

linux进阶高级配置,你需要知道的有哪些(8)-shell脚本应用(三)

1、for循环语句的结构&#xff1a; for 变量名 in 取值列表 do 命令序列 done 2、while循环语句结构&#xff1a; while 条件测试 do 命令序列 done 3、for和while的区别 for:控制循环来自于取值列表 while&#xff1a;控制循环来自于条件测试 4、case语句的…...

安全测试|常见SQL注入攻击方式、影响及预防

SQL注入 什么是SQL注入&#xff1f; SQL注入是比较常见的网络攻击方式之一&#xff0c;主要攻击对象是数据库&#xff0c;针对程序员编写时的疏忽&#xff0c;通过SQL语句&#xff0c;实现无账号登录&#xff0c;篡改数据库。 SQL注入简单来说就是通过在表单中填写包含SQL关键…...

【Git】Git在Gitee上的基本操作指南

文章目录 1. 查看 git 版本2. 从Gitee克隆仓库&#xff1a;3. 复制文件到工作目录&#xff1a;4. 将未跟踪的文件添加到暂存区&#xff1a;5. 在本地提交更改&#xff1a;6. 将更改推送到远程仓库&#xff08;Gitee&#xff09;&#xff1a;7. Windows特定提示&#xff1a; 1. …...

国债期货怎么买?十年国债交易手册

国债&#xff0c;简单来说&#xff0c;就是国家为了筹集资金而向大众借钱的一种方式。国家通过发行债券&#xff0c;向投资者承诺在约定的时间里支付利息&#xff0c;并在到期时归还本金。因为是国家发行的&#xff0c;所以国债的信用等级非常高&#xff0c;通常被认为是非常安…...

公司申请增加公众号数量

一般可以申请多少个公众号&#xff1f;众所周知&#xff0c;在2013年前后&#xff0c;公众号申请是不限制数量的&#xff0c;后来企业开始限制申请50个&#xff0c;直到2018年的11月tx又发布&#xff0c;其中个人主体可申请公众号由2个调整为1个&#xff0c;企业主体由50个调整…...

什么是.faust勒索病毒?应该如何防御?

faust勒索病毒详细介绍 faust勒索病毒是一种新型的勒索软件&#xff0c;最早出现在2018年。该病毒通过加密计算机系统中的文件并要求支付赎金来解锁文件&#xff0c;从而获取经济利益。与传统的勒索软件相比&#xff0c;faust勒索病毒采用了更加先进的加密算法和隐藏技术&#…...

邓闲小——生存、生活、生命|真北写作

人生有三个层次∶生存、生活、生命。 生存就是做必须做的事。生存的模式是邓&#xff0c;是交易&#xff0c;是买卖。别人需要的东西&#xff0c;你生产出来&#xff0c;卖给他。哪怕这个东西没啥用&#xff0c;也可以卖&#xff0c;情绪也可以卖。你需要的东西&#xff0c;你花…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

机器学习的数学基础:线性模型

线性模型 线性模型的基本形式为&#xff1a; f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法&#xff0c;得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...