避坑指南:通过expdp/impdp迁移数据的7个坑

时间:2022-07-23
本文章向大家介绍避坑指南:通过expdp/impdp迁移数据的7个坑,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

墨墨导读:expdp/impdp是一个非常简单的操作,但是简单的操作中往往蕴藏了很多原理性的东西,如果稍不注意,则可能会才到很多坑。

背景

客户更新生产库中的一些核心数据,所有核心数据更新的时间需在2天内完成。为了配合业务对数据更新时间进行演练和预估,客户要求将10T+核心数据导入到新的库中。全过程使用expdp导出,然后传输数据文件到目标端,最后用impdp导入。

这里总结整个过程中遇到的问题和经验,供大家参考,希望大家遇到同类情况可以规避这7种错误。

问题1 :在导出导入前未充分调研需要迁移的数据量

在之前做的一些迁移(不管是逻辑还是物理),如果不是空间非常紧张,我一般只会对数据文件或者表空间的大小进行调研,要求新环境的数据文件或表空间要大于源环境的数据文件即可。

但这次只是迁移部分数据,所以我在调研的时候,主要是通过dba_segments的方式来判断(已经确定这些表中没有LOB字段)。可是在选择segment_type的时候,我只筛选了其中相关的TABLE,而没有对其他的相关对象进行评估。因此,最开始评估出来的数据只有4T左右。而实际上相关对象还有索引等(索引是最大的),加起来总共有近10T的大小。而这也导致我在迁移的时候,在最后表空间很紧张。

那么这里我也大概写了一个对数据里量和相关索引量调研的查询SQL语句,供参考:

--table:
select owner,segment_name,tablespace_name,sum(bytes)/1024/1024/1024 gb from dba_segments where segment_name ='TABLE_NAME1' and owner='USER' group by owner,segment_name,tablespace_name;

--index:
select owner,segment_name,tablespace_name,sum(bytes)/1024/1024/1024 gb from dba_segments where segment_name in(select index_name from dba_indexes where table_name='TABLE_NAME1' and owner='USER') and owner='USER' group by rollup(owner,segment_name,tablespace_name);

问题2 :传输文件到源端

由于客户要求精确报告进度,所以要求每张表导出一个数据文件。所以总共导出了20多个数据文件。大小有1T+。

在传输文件过程时,本想偷懒用脚本在后台进行,就不需要人工看着。所以通过except方式写了个shell脚本,对这些文件进行后台scp传输,但是脚本跑起后,回到家才发现,每个文件只传输了几兆,任务就中断不再传输了。测试了好几遍,发现通过nohup进行scp的时候,传输一会儿任务自己就掉了(目前还不太清楚是为什么),所以最后就只能还是通过前台进行文件传输了。

问题3 :目标端表空间创建

在进行impdp的时候,如果我们在impdp语句中不加remap_tablespace参数时,我们就必须要创建和源端一样的表空间。如果导出导入的数据表中存在不一致的表空间,则会报错中断。而由于我前期没有充分调研,发现在导出的表中,其索引全部是在一个单独的表空间中,所以导入时由于索引表空间不存在而失败。

当然,如果没有强制要求(比如这里我们只是进行测试),懒得创建一模一样的表空间时,我们也可以在导入时加入remap_tablespace参数,将源端表空间remap到新建表空间。但是,这也必须知道我们的源端表空间有哪些,remap_tablespace参数中,必须要将源端到目标端表空间map关系写全。

问题4 :临时表空间

在导入数据索引的时候一定要注意临时表空间的大小。由于逻辑导入索引,实际执行的还是create index命令,所以一定会占用临时表空间,虽然期间也会释放,但是当遇到一个非常大的索引时候,则可能会引起临时表空间不足而导致导入任务卡住超时。

而由于本次迁移的数据索引量巨大,所以在导入前一定要扩展临时表空间,否则会出现问题。

问题5 :undo

在导入数据及索引的时候,其过程核心还是进行DDL、DML等操作,而这一定会产生事务,只要使用到事务,就一定会用到undo表空间。所以我们也需要时刻关注undo表空间的大小。不足的时候,可以临时调整undo_retention或undo的大小。

问题6 undo_retention大小问题

像上一条说的,导入会产生事务,所以我们有时要唔该undo_retention的大小,但是该参数大小如何调整呢?如果调整的太大,undo释放的慢,undo表空间很快就会满;如果调整的太小,undo释放的快了,但是导入可能会出现ORA-01555的错误。所以我们需要将undo_retention调整到适中大下。本次迁移,我将undo扩展为160G。undo_retention保留为1小时。在后面的导入过程中没有出现任何问题。

问题7 :如何提高效率

通过一条impdp语句导入时候,如果没有Lob字段,仅有数据,导入还是非常的快,比如500G的数据,大概20分钟就导入了。而创建索引的过程是非常慢的。所以为了提高速率,我们可以通过impdp将索引导为sql file,然后手动对索引的创建加入并行度(加了并行后,一定要在脚本里对创建完成的索引,将并行度改回1),并对脚本进行拆分,使用多个会话进行索引创建(这样,就更需要注意temp表空间了)从而提高索引创建速度。