oracle lob表迁移,Oracle 19c迁移遇到大容量lob表怎么办?

原标题:Oracle 19c迁移遇到大容量lob表怎么办?

63566142ce51f0e791459c509f888356.png

作者介绍

梁铭图,新炬网络首席架构师,十多年数据库运维、数据库设计、数据治理以及系统规划建设经验,拥有Oracle OCM、Togaf企业架构师(鉴定级)、IBM CATE等认证,曾获dbaplus年度MVP以及华为云MVP等荣誉,并参与数据资产管理国家标准的编写工作。在数据库运维管理和架构设计、运维体系规划、数据资产管理方面有深入研究。

王涛,新炬网络资深数据库专家,长期服务于运营商、金融、制造业及政企客户。扎根客户一线,多次主导运营商数据库大版本升级,擅长数据割接及同步技术的研究和应用,割接实战经验丰富。

背景

从Oracle数据库官方服务支持生命周期表,我们可以清晰看到Oracle 11g已过主支持生命周期,2020年后不再支持。基于这个背景,某客户的应用系统数据库将从IBM AIX小型机环境迁移到某国产数据库一体机,同时数据库版本从11g直接升级为19c。

01b83c7a48f9373b5879257bb1ca8d64.png

LOB字段带来的问题

经过分析,此数据库的数据量不大,只有区区3TB,同时由于停机时间非常充分,可以考虑采取数据泵datapump的方式实现数据迁移。但是在仔细查看后,发现数据库中有个单表2TB,仔细再查2TB基本全是lob字段,且不是分区表,这个问题就有点棘手了。

fb77845a203d6281767b84488c0c7b46.png

根据以往的经验来看,这种大容量TB级的lob表,使用以往常规导出的方式,大概率会报Ora-01555。

18f6b40b4317aa9225e71718af5ce0a2.png

稍稍测试一下,果不其然。

解决方法

一般的方法可以修改一下undo_retention参数以及lob字段的retention设置来解决,大致如下:

alter system set undo_retention=7200 scope=both;

alter table table_name MODIFY LOB(col_name)(retention);

然而当前的数据库是一个生产环境,参数修改这样的风险工程还是少做为妙,因此需要另辟蹊径。既然ORA-01555是由于长时间查询引起,我们可以尝试减少倒出的数据量。

最后决定用Expdp的Query试一试,但是2TB的数据量的单表lob还是第一次,那么根据哪个条件进行Query导出呢?

首先需考虑到是根据主键和索引列进行导出,这样的效率会比较高。确认后,问题又来了,索引列不满足均匀分批条件,故这个思路走不通了。

要怎样才能均分呢?看来只能用Rowid试试看。

首先Rowid是用于定位数据库中一条记录的一个相对唯一地址值。通常情况下,该值在该行数据插入到数据库表时即被确定且唯一。Rowid是一个伪列,它并不实际存在于实体表中。

它是Oracle在读取表中数据行时,根据每一行数据的物理地址信息编码而成的一个伪列。所以根据一行数据的Rowid能找到一行数据的物理地址信息,从而快速地定位到数据行,而且使用Rowid来进行单记录定位速度是最快的。

4f74ee1b8209f2c2406407c100f1113a.png

上图是Rowid的结构图,主要包含4个部分:

第一部分6位表示:该行数据所在的数据对象的Data_object_id

第二部分3位表示:该行数据所在的相对数据文件的id

第三部分6位表示:该数据行所在的数据块的编号

第四部分3位表示:该行数据的行的编号

一个扩展Rowid采用10个byte来存储,共80bit,其中obj#32bit, rfile#10bit, block#22bit, row#16bit。所以相对文件号不能超过1023,也就是一个表空间的数据文件不能超过1023个(不存在文件号为0的文件),一个Datafile只能有2^22=4M个 block,一个block中不能超过2^16=64K行数据的由来。

了解了Rowid后,怎么进行均匀分批呢?我们可以利用Oracle提供的DBMS_ROWID 包。

f8170d6fbfbf9a6406645489dd4821f7.png

导出脚本修改如下:

b598af6f9076189c57bce5e0d520176d.png

参数说明:

Content=DATA_ONLY:只导出表中的数据,导出会更快,导入时也更快,index之类的对象在data导入后单独处理;

COMPRESSION=DATA_ONLY:数据量太大,节省空间,传输到新环境时效更高;

Query=“……”:将表数据根据条件进行分批导出全部数据。

为什么选用rowid_block_number呢?因为导出这个大表的需求下,Object_id就一个,分不了批次,Fileid只有150个,BLOCK_ID 是126924个,ROW_NUMBER是19,数据量数值进行Mod取余分批的差异就越小,所以使用rowid_block_number。使用这个方法后还是很顺利地导出了数据。

f22d1bf9a20de98579ab35aabd5bf703.png

将参数文件复制并修改取模的余数值,分为十个进程并发执行。查看全部导出日志,每个批次耗时相差不大,满足均匀分批导出的计划。

47a60618dfdb14810df23531b095face.png

小结

遇到超大lob表导出需要,一般的思路是尽可能通过分区或者过滤查询减少单表数据导出的数据量,减少整体耗时,办法可以分为:

1、查看是否是分区表,分区表的话按分区导出:

userid=' / as sysdba'

directory=DMP

dumpfile=export.dmp

logfile=export.log

CONTENT=DATA_ONLY

COMPRESSION=DATA_ONLY

tables=(

onwer.tbale_name:part_name

2、业务沟通,是否存在均匀分布的字段值,按照字段值分批导出,例如:

USERID=' / as sysdba'

directory= DMP

CONTENT=DATA_ONLY

COMPRESSION=DATA_ONLY

dumpfile=export.dmp

logfile=export.log

tables=owner.table_name

QUERY="WHERE column_name > 100000

3、不满足以上的都可以使用本文rowid方式进行导出:

Cat exp_owner_table_seq.par

USERID='/ as sysdba'

directory= DMP

CONTENT=DATA_ONLY

COMPRESSION=DATA_ONLY

dumpfile=export.dmp

logfile=export.log

tables=owner.table_name

QUERY="wheremod(dbms_rowid.rowid_block_number(rowid),10)=1"

云时代下数据库将如何革新与创变?金融行业核心数据库迁移与建设如何安全平稳展开?开源技术如何在实际业务场景中发挥实力?11月6日,DAMS中国数据智能管理峰会将在上海举办,专设【数据库分场】,部分议题如下:

《All in Cloud时代,下一代云原生数据库技术与趋势》阿里巴巴 集团副总裁 李飞飞(飞刀)

《金融行业分布式数据库需求及选型》工商银行 数据中心系统三部副总经理 赵永田

《从自研演进看分布式数据库》中国银联 云计算中心团队主管 周家晶

《开源数据库MySQL在民生银行的应用实践》民生银行 项目经理 徐春阳

责任编辑:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值