expdp之我们到底是不是同年同月同日生?

在某个下午,小编的一个可爱的客户抛了个问题过来:


expdp在导出时,如果不指定flashback_scn或者flashbackup_time参数的话,导出的数据的scn是一致的吗?


所有表是同一个时间点的数据吗?

既然你诚心诚意的发问了,我就有问必答的告诉你:


expdp导出的时候,导出表之间并没有一致性保证,每张表都有自己的scn。


虽然从10g开始,oracle将以下信息放在了导出信息头部:

运维日记|expdp之我们到底是不是同年同月同日生?

但这只意味着某些表将被分配特殊的scn(Streams 和Logical Standby所需)。导出的表之间并不能保证一致性。


我们可以做个简单的实验:


1. 创建一个实验环境。我们创建用户usr001,并在这个用户下创建了一张分区表。

运维日记|expdp之我们到底是不是同年同月同日生?


2. 填充分区表:分区P001包含50000行,分区P002包含100行

运维日记|expdp之我们到底是不是同年同月同日生?


3. 使用expdp导出该表。

运维日记|expdp之我们到底是不是同年同月同日生?


4. 在导出的同时,另开一个窗口从P002分区删除5条数据。

运维日记|expdp之我们到底是不是同年同月同日生?


5. 观察完整的导出日志。

运维日记|expdp之我们到底是不是同年同月同日生?


我们可以观察到,P002分区表只导出了95行数据,这就说明了,在默认情况下,expdp导出过程是不具备一致性的。


当然了,如果用户有这样的类似于一定要保证导出表一致性的需求,除了建议在停止相关业务再做导出外,oracle官方也提供了以下两个参数保证expdp导出的一致性:


1. 使用Oracle导出参数 flashback_scn或者flashbackup_time来指定数据导出的时间点或scn点。


2. 另外,可以使用consistent=y参数去保证导出数据一致性。这个参数是exp命令上的传统参数。


expdp在使用该参数后,我们在日志中可以看到:

运维日记|expdp之我们到底是不是同年同月同日生?


可以看到这个参数后台是将其转换成了FLASHBACK_TIME参数,导出时间绑定为SYSTIMESTAMP时间,即当时数据库时间。


你们以为这样就结束了吗,当然不是。


小编的客户又问了一个问题 :


那expdp导出的时候,假如我对一组有着主外键的表的父表做了删除操作,那oracle是怎么保证导入到其他环境的时候,主表及子表的主外键关系正常的呢?


答案就是:


Oracle默认在导出数据的时候,按照顺序先导出的父表,然后再导出子表,这样子无论对父表做任何的操作,父表的数据都是早于子表的。


我们举个例子:


1. 在用户usr001建立三张表,dept为emp的父表、emp又为price的父表。

运维日记|expdp之我们到底是不是同年同月同日生?

运维日记|expdp之我们到底是不是同年同月同日生?


2. 我们对usr001用户做导出:

运维日记|expdp之我们到底是不是同年同月同日生?

我们可以看到,在导出表数据之前,expdp有一些数据分析处理工作,其中有一步就是外键约束信息收集。


运维日记|expdp之我们到底是不是同年同月同日生?

在导出数据表信息中,我们发现oracle按照父-子表的顺序先后导出了这些表。


分享到:


相關文章: