天天看点

Oracle Data Pump Internals

简介

甲骨文数据泵是甲骨文数据库 10g 第 1 版中引入的一项新功能。Oracle 数据

泵导出 (expdp) 和导入 (impdp) 实用程序是原始导出 (exp)

和导入 (imp) 实用程序的替代品。Oracle 数据泵支持在 Oracle 数据库之间非常快速地移动

批量数据和元数据。它速度快,使用并行线程,并受命令行

客户端(expdp 和 impdp)以及基于 Web 的 Oracle 企业管理器界面的支持。与原始实用程序相比,

一些原始的关键增强功能包括:

  • 并行执行
  • 对象选择
  • 重启能力
  • 网络操作(通过数据库链接导出/导入,而无需使用转储文件。

并行操作:

Oracle 数据泵用户可以指定 Oracle 数据

泵实用程序可以使用的最大并行线程数。此值表示 MCP 为完成事务可以启动

的最大进程数。此数字不包括 MCP 进程,如下

所述。在某些情况下,为并行指定的值太大,Data Pump 只会

启动完成任务所需的其他线程。

当数据抽取作业启动时,至少会创建 2 个进程。第一个过程称为

MCP(主控制过程)。其功能是验证所有参数和职位描述。它还

控制工作项并将其分配给工作进程。启动的第二个进程是

工作进程。此过程将打开与元数据 API 的通信以导出或导入

ddl,并打开与数据层的通信以卸载或加载数据。如果未指定并行参数

,或者指定了值 1,则这些是将为作业启动

的唯一 2 个进程。如果指定了大于 1 的并行值,则将创建其他进程。

这些附加进程将是工作进程和并行执行 (PQ)

从进程的组合。

并行导出操作:

当同时包含元数据和数据的 Oracle 数据泵导出作业以大于 1 的并行

值启动时,第一个工作进程将导出所有元数据。此

工作进程将执行的第一个任务是估计需要导出哪些数据。此时收集的信息

称为“TABLE_DATA”对象。这些对象描述

子分区表的每个子分区、分区表的每个分区以及每个表(如果未分区或

分区)。估计阶段完成后,MCP 将使用剩余的并行

进程导出与这些TABLE_DATA对象关联的数据,而第一个工作

进程将继续导出元数据。MCP 进程将确定要分配给工作进程的TABLE_DATA

对象,它还将决定将为每个工作

进程分配多少并行性值。如果为工作线程分配了大于 1 的并行度值,则将使用并行

执行从站(PQ 从站)导出TABLE_DATA对象中的数据。当使用PQ

从站时,工作进程是查询协调器,它不考虑总

并行值。

下面是两个示例,说明在将并行设置为 6 的情况下导出时可能发生的情况。第一个

示例包含大量数据,第二个示例包含最少的数据。

示例 1:使用并行 = 6 的导出作业启动的进程 – 大量数据

(数据由 2 个大子分区和 1 个小子分区组成)

  • MCP – 不适用于并行 6 值
  • 辅助角色 1 – 卸载元数据 – 1 个并行进程
  • 辅助角色 2 – 卸载子分区用户1:选项卡 1:子部分 1 - 2 个并行度

o Worker2_PQ1 – 卸载数据 – 1 个并行进程

o Worker2_PQ2 – 卸载数据 – 1 个并行进程

  • 辅助角色 3 – 卸载子分区用户1:选项卡 1:子部分 2 - 1 个并行度
  • 辅助角色 4 – 卸载子分区用户1:选项卡1:子部件 3 - 2 个并行度

o Worker4_PQ1 – 卸载数据 – 1 个并行进程

o Worker4_PQ2 – 卸载数据 – 1 个并行进程

示例 1 摘要:执行工作的进程(不是 MCP,也不是充当查询协调器的工作

进程)的总和 = 6。在此测试用例中,您将看到有 4 个工作线程,但

其中 2 个是查询协调器。您还将看到有4个PQ从站。

在某些导出作业中,可能没有足够的数据来使用所有可用的并行进程。

如下面的示例 2 所示。

示例 2:使用并行 = 6 的导出作业启动的进程 – 非常少的数据(数据

由 1 个小表组成)

  • MCP – 不适用于并行 6 值
  • 辅助角色 1 – 卸载元数据 – 1 个并行进程
  • 工人 2 – 卸载小表 用户 1:表 1 – 1 过程

示例 2 摘要:即使指定了并行 6,也只能看到 2 个工作线程。

对于导出作业,强烈建议您为指定的最大并行线程数

指定足够的转储文件。由于只有一个进程可以写入转储文件,因此,如果未指定

足够的转储文件,则运行的并行线程数将限制为已指定的转储文件

数。

还建议在指定转储文件时指定不同的 I/O 控制器。

这将避免在多个线程同时将数据

写入转储文件时出现潜在的 I/O 瓶颈。

并行导入操作:

导入作业使用并行的方式不同。由于对象存在依赖关系问题,因此需要

按特定顺序创建某些对象。表空间需要在用户之前创建,用户在表之前创建,表

在索引之前创建,等等。由于依赖关系问题,大多数元数据都是按顺序创建的。也有

一些例外。包体是并行创建的,索引是使用并行执行

从站构建的。包含数据和元数据的典型导入将遵循以下步骤:

  1. 按依赖关系顺序创建元数据,并在创建表后停止(全部按顺序完成)
  2. 使用最大并行度导入数据。

    注: 用于导入数据的并行算法与导出数据的并行算法相同。如果有益,则

    使用PQ从站,并且进程使用最大并行值达到指定的最大并行值。

  3. 按依赖关系顺序创建元数据,直到包正文。(连续)
  4. 使用并行工作进程创建包正文
  5. 按“依赖关系顺序”创建元数据,直到索引(串行)
  6. 按顺序创建索引,但使用 pq 从站来构建它们。
  7. 完成剩余元数据的导入。(连续)

包体被分割到指定的最大平行值。例如,如果您有

20 个文件包正文(假设所有文件在导出时大小大致相同),并且

指定了 parallel=5,则 MCP 将启动 5 个工作进程,每个进程将分配 4 个包裹正文。

对于索引创建,每个索引都是按顺序创建的,但索引中的并行值将被修改

为 Data Pump 作业的并行值。如果您的索引是这样创建的:

创建唯一的索引“HR”。EMP_EMP_ID_PK“在”HR“上。雇员“

(”EMPLOYEE_ID“)

PCTFREE 10 INITRANS 2 MAXTRANS 255

存储(初始 16384 下一页 16384 MINEXTENTS 1 最大扩展 505

PCITS 505 PCITS 50 自由列表 1 自由列表组 1

BUFFER_POOL默认FLASH_CACHE默认CELL_FLASH_CACHE默认)

表空间”系统“并行 3 ;

然后,如果您使用 parallel=22 执行导入,则创建索引将按以下 2 个语句执行。

创建唯一的索引“HR”。EMP_EMP_ID_PK“在”HR“上。雇员“

(”EMPLOYEE_ID“)

PCTFREE 10 INITRANS 2 MAXTRANS 255

存储(初始 16384 下一页 16384 MINEXTENTS 1 最大扩展 505

PC创新 50 自由列表 1 自由列表组 1

BUFFER_POOL默认FLASH_CACHE默认CELL_FLASH_CACHE默认)

表空间”系统“并行 22 ;

这将使用多达22个PQ从站来尽快构建索引。构建后,将执行以下

命令。

更改索引“HR”。EMP_EMP_ID_PK“ 平行 3;

这会将原始并行值还原到索引。数据抽取完成后,目标是

恢复原始设置,因此需要恢复并行值 3。在运行数据泵

导入时,Oracle 可以选择使用少于 22 个 pq 从站来构建索引,但数据泵为 Oracle 提供了

使用最多 22 个从站的选项。实际值是通过查看索引,

关联表,表中有多少数据等

来确定的,数据泵数据移动方法:

Oracle数据泵使用三种不同的方法来移动数据。选择的方法由许多不同的

因素决定。这些因素包括表定义中使用的类型、

用户选择的方法、是否指定链接、是否指定了筛选器或重映射、表中

数据的大小以及 Data Pump 作业中的数据总量。可用的三种方法是“

直接路径”、“外部表”和“通过网络链接作为选择插入”。

表定义中使用的类型可以消除某些方法。外部表不支持

移动长整型或长整型原始数据,因此,如果表具有长整型或长整型原始表,则无法选择外部表。

导入到预先存在的分区表中时,由于从源到目标的字符集

已更改,分区方案可能会有所不同。在这种情况下,将使用外部表。不允许使用直接

路径。

客户可以通过以下方式专门选择访问方法:

ACCESS_METHOD=EXTERNAL_TABLES

在这种情况下,数据泵将使用外部表。如果无法使用此方法移动数据,

则会报告错误。如果作业中的某个表具有长列,则会出现这种情况。

在这种情况下,不会导入与具有长列的表关联的数据,并且会向用户报告一条错误消息

如果指定了网络链接、查询子句或remap_data转换,则唯一可能的解决方案

是通过网络链接使用外部表或“作为选择插入”。

如果作业是网络导入,则唯一的解决方案是“作为选择插入”。数据将通过从

远程表中进行选择直接插入到本地表中。

如果上述方案都不存在,并且可以使用任何可能的方法加载数据,则

主控制进程(如上所述)将根据表大小、作业

大小和指定的并行值选择最佳方法。如果只有 1 个表且表很大,则 MCP 将

选择具有最大并行值的外部表。这允许工作进程使用PQ

从站来移动数据。如果作业包含许多较小的表,则设置

外部表的开销成本将不会有利。使用直接路径并允许

多个工作人员为单个表导入数据会快得多。内部测试表明,Direct Path 比外部表快

大约 2 倍,因此,如果表足够小,

则直接路径加载或卸载可能会在配置外部表进程之前完成。

导出数据时,需要先导出较大的表,尤其是在指定了大于 1 的并行

值时。如果不是这样做的,并且最后

导出最大的表,并且无法使用并行线程导出该表,则在导出此表中的数据时,剩余的并行

进程将处于空闲状态。如果

首先导出同一个表,则剩余的并行线程可能忙于从其他表导出数据,从而使它们保持

忙碌并减少导出作业完成的总时间。使用此算法,如果一个小表

是最后一个并且不能使用并行线程,则剩余的并行线程仍将处于空闲状态,

但由于该表很小,因此它将更快地完成。

Oracle 数据泵主表

当 Oracle 数据泵作业正在运行时,它将使用“主表”来跟踪它

在特定作业中的位置。在导出过程中,当对象信息写入转储文件时,位置和

简要说明将插入到主表中。当导出 jb 完全导出时,主表的内容

将写入转储文件。在导入过程中,导入的第一个信息是

主表。从这里,数据泵包可以确定导出的内容并确定

需要导入的内容。

拥有此表的一些好处是,在执行导入操作和

仅导入对象的子集时,可以提高速度。在 exp/imp 转储文件中,转储文件是连续的。

假设您导出了 2 个表和 2 个索引。转储文件将如下所示:

创建表“斯科特”。傅“ ...

创建表“斯科特”。酒吧“...

创建独特的索引“斯科特”。BAR_IND“在”斯科特“上。酒吧“...

创建独特的索引“斯科特”。FOO_IND“在”斯科特“上。傅“...

如果您只想导入 SCOTT 的信息。BAR(表和索引),然后 imp

实用程序必须读取完整的转储文件才能找到与 scott.bar 关联的 ddl,scott.bar_ind

。使用数据泵,xml 将写入转储文件,并在

主表中插入一行,指示对象类型、对象架构、对象名称、转储文件位置。因此,对于数据

泵,主表将具有类似于以下内容的行:

object_type object_schema object_name dumpfile_location

表 斯科特 FOO 1234

表 斯科特 BAR 1235

指数 斯科特 FOO_IND 1236

指数 斯科特 BAR_IND 1237

由于 scott.bar 和scott.bar_ind将被导入,因此数据泵进程仅读取块 1235 和 1237 处

的信息。斯科特.foo和scott.foo_ind的信息永远不会被读取。

这可以提高应用筛选器时导入作业的性能。

在数据抽取作业期间,主表的内容保持最新。这在

作业停止的情况下是有益的。为了重新启动已停止的作业,数据泵包会查询主表以查看

重新启动的位置。

Oracle 数据泵导出重新启动

如果 Oracle 数据泵导出作业曾经停止过,通常可以重新启动它。无法

重新启动一些作业。其中一些是:使用可传输表空间的作业,以及尚未完成估计阶段

的作业。对于可以重新启动的导出作业,重新启动它的关键因素是主表

的存在。

在导出期间,在导出元数据时,工作进程会跟踪它正在处理的内容。

它通过在主表中输入行来执行此操作。例如:如果正在导出用户,则当

工作进程获取第一个用户的元数据时,它会在主表中创建一个名为“TYPE COMPLETION”

行的行,指示 USERS 正在导出过程中。此类型完成行中的一些

信息是对象类型,当前时间存储在名为start_time的

列中,等等。然后,它为每个类型创建一个 OBJECT 行(如上面的表/索引

示例所示)。导出所有用户后,工作进程将使用completed_time更新类型完成行

。对于导出的每种类型的对象,将重复此操作。

如果要停止导出作业(手动停止、系统故障或其他原因),则不会删除主表

。重新启动此作业时,工作进程将查找类型完成行

,以查看哪些start_time但没有completed_time。例如:

object_type start_time completion_time

表空间 12-sep-2012:9:04.01 12-sep-2012:9:05.23

用户 12-sep-2012:9:05.27

在此情况下,工作进程检测到用户正在导出。在此情况下,Data

Pump 将删除描述用户的所有行,删除描述

用户正在进行的类型完成行,并删除存储在描述用户的转储文件中的 xml。然后

,它将元数据 API 配置为在 TABLESPCE 之后启动,因为表空间是最后一个完整的对象

类型。

如果没有具有空completion_time的类型完成行,如以下示例所示:

object_type start_time completion_time

表空间 12-9-2012:9:04.01 12-sep-2012:9:05.23

用户 12-sep-2012:9:05.27 12-9-2012:9:07.34

工作进程将检测到没有任何正在进行的操作,因此不必删除任何行,不会从转储文件中删除任何

XML,并且元数据 API 将配置为在“USER”类型之后

启动。

如果使用命令行界面停止作业,请小心选择哪个选项。停止

选项将停止作业并允许其重新启动。kill 选项将停止作业并

删除主表。删除主表后,将无法再重新启动作业。

Oracle 数据抽取导入重新启动

如果 Oracle 数据抽取导入作业曾经停止过,只要主表

存在,就可以重新启动该作业。导入重新启动代码在重新启动时也会使用主表。它不是查看

类型完成行,而是查看对象行。对象行中有状态和状态字段,用于

检测哪些对象已导入以及哪些对象仍需要导入。下面是上面显示的

表/索引示例的示例。在此示例中,表 scott.foo 和 scott.bar 及其索引一

起导出。在导入开始时,描述这些对象的

行将如下所示:

类型 object_schema object_name processing_state processing_status

表 斯科特 FOO R C

表 斯科特酒吧 R C

索引 斯科特 FOO_IND R C

指数 斯科特 BAR_IND R C

“R”的状态字段表示对象已被检索(或导出)。“C”

的状态表示对象是“当前”(或信誉良好)。如果导入作业在 scott.foo 导入后和导入 scott.bar 之前启动,然后

停止,则行将如下所示:

类型 object_schema object_name processing_state processing_status

表 斯科特 FOO W C

表 斯科特酒吧 U C

索引 斯科特 FOO_IND R C

索引 斯科特 BAR_IND R C

这表明表 scott.foo 是“W”写入或导入的,“C”的状态显示它是

当前或成功的。对于表 scott.bar,导入已开始导入此对象,但从未

完成。未知的“U”状态显示了这一点。对象仍然是 C 电流,因此它没有失败。

当数据泵导入重新启动时,它将找到此行,导入作业将从此处继续。将

再次导入 Scott.bar 表。创建表后,导入作业将继续处理其余

对象。在本例中,这些索引将是 2 个索引。