当前位置导航:炫浪网>>网络学院>>编程开发>>Oracle教程

Oracle10g:数据的导入导出


  给数据泵加压
  
  Oracle 数据库 10g 中的新的实用程序使其性能和多功能性达到了新的水平。
  
  Oracle 数据库 10g 中增加的叫做 Oracle Data Pump (数据泵)的新的导入和导出特性,彻底改变了数据库用户已经习惯的过去几代 Oracle 数据库的客户 / 服务器工作方式。现在服务器可以运行导出和导入任务。你可以通过并行方式快速装入或卸载大量数据,而且你可以在运行过程中调整并行的程度。导出和导入任务现在可以重新启动,所以发生故障不一定意味着要从头开始。 API 是公诸于众的,并且易于使用;用 PL/SQL 建立一个导入和导出任务非常简单。一旦启动,这些任务就在后台运行,但你可以通过客户端实用程序从任何地方检查任务的状态和进行修改。
  
  体系结构
  
  在 Oracle 数据库 10g 之前(从 Oracle7 到 Oracle9I ),导入和导出实用程序都作为客户端程序运行,并且完成大量工作。导出的数据由数据库实例读出,通过连接传输到导出客户程序,然后写到磁盘上。所有数据在整个导出进程下通过单线程操作。今天的数据量比这个体系结构最初采用的时候要大得多,使得单一导出进程成了一个瓶颈,因为导出任务的性能受限于导出实用程序所能支持的吞吐量。
  
  在 Oracle 数据库 10g 和全新的数据泵( Data Pump )体系结构下,如今所有的工作都由数据库实例来完成。数据库实例可以用两种方法来并行处理这些工作:通过建立多个数据泵工作进程来读 / 写正在被导出 / 导入的数据,以及建立并行 I/O 服务器进程以更快地选取( SELECT )或插入( INSERT )这些数据。这样,单进程瓶颈再也就不存在了。
  
  数据泵任务用新的 DBMS_DATAPUMP PL/SQL API 来建立、监测和调整。新的导入和导出实用程序(分别为 impdp 和 expdp )对于这个 API 来说只是命令行接口。你可以使用数据泵导出实用程序初始化一个任务,例如一个导出任务。然后你就可以关闭你的客户端,回家过夜和享用晚餐,而你的任务会一直运行。到了深夜,你可以重新连接到那个任务,检查其状态,甚至可以提高并行程度,以便在深夜系统没有用户在用的情况下多完成一些工作。第二天早上,你可以降低并行度甚至挂起该任务,为白天在线的用户释放资源。
  
  重新启动任务的功能是数据泵体系结构的一个重要特性。你可以随时停止和重启动一个数据泵任务,比如为在线用户释放资源。你还可以从文件系统的空间问题中轻松地恢复。如果一个 12 小时的导出任务在进行了 11 小时后因磁盘空间不够而失败,那么你再也不用从头开始重新启动该任务,重复前面 11 小时的工作。而是你可以连接到这个失败的任务,增加一个或多个新的转储( dump )文件,从失败的地方重新启动,这样只需一个小时你就可以完成任务了。这在你处理很大数据量时非常有用。
  
  对文件系统的访问
  
  由服务器处理所有的文件 I/O 对于远程执行导出和导入任务的数据库管理员来说非常有利。如今,用户可以很轻松地在类似 UNIX 的系统 ( 如 Linux) 上 telnet 或 ssh 到一个服务器,在命令行方式下初始化一个运行在服务器上的导出或导入任务。然而,在其他操作系统上就不那么容易, Windows 是最明显的例子。在推出数据泵之前,要从一个 Windows 系统下的 Oracle 数据库中导出大量数据,你很可能必须坐在服务器控制台前发出命令。通过 TCP/IP 连接导出数据只对小数据量是可行的。数据泵改变了这一切,因为即使你通过在你的客户端上运行该导出和导入实用程序来初始化一个导出或导入任务,该任务其实也运行在服务器上,所有的 I/O 也都发生在该服务器上。
  
  出于安全性考虑,数据泵要求你通过 Oracle 的目录对象来指定其中存放着你要建立或读取的转储文件的目标目录。例如:
  
  CREATE DIRECTORY export_dumps
  
  AS 'c:\a';
  
  GRANT read, write
  
  ON DIRECTORY export_dumps
  
  TO gennick;
  
  我以 SYSTEM 身份登录到我的实验室数据库上,并执行以上语句来建立一个目录对象,这个目录对象指向了我磁盘上的一个临时目录,以用来存放导出的转储文件。 GRANT 语句为用户 gennick- 就是我 - 分配了访问该目录的权限。我给自己分配读 / 写权限,因为我将导出和导入数据。你可以为一个用户分配读权限,限制他只能导入数据。
  
  启动一个导出任务
  
  你可以使用新的 expdp 实用程序来启动一个导出任务。因为参数与老的 exp 实用程序不同,所以你得熟悉这些新的参数。你可以在命令行中指定参数,但在本文中我使用了参数文件。我想导出我的整个模式( schema ),使用了以下参数:
  
  DUMPFILE=gnis%U.dmp
  
  DIRECTORY=export_dumps
  
  LOGFILE=gnis_export.log
  
  JOB_NAME=gnis_export
  
  DUMPFILE 指定我将向其中写入被导出数据的文件。 %U 语法给出了一个增量计数器,得到文件名 gnis01.dmp 、 gnis02.dmp 等。 DIRECTORY 指定了我的目标目录。
  
  我的 LOGFILE 参数指定了日志文件的名字,这个文件是为每个导出任务默认创建的。 JOB_NAME 给任务指定了一个名字。我选择了一个易于记忆(和输入)的名字,因为我可能需要在后面才连接这个任务。要注意在指定任务名称时不要与你登录模式( schema )中的模式对象名称冲突。数据泵在你的登录模式中建立一个被称为任务主表的数据表,该表的名字与任务的名字相匹配。这个数据表跟踪该任务的状态,并最终被写入转储文件中,作为该文件所含内容的一个记录。
  
  清单 1 显示了一个导出任务已被启动。该任务所做的第一件事是估计所需的磁盘空间大小。当估计值显示出来后,我按 ctrl-C 进入一个交互式的导出提示窗口,然后使用 EXIT_CLIENT 命令回到我操作系统的命令窗口。该导出任务仍然运行在服务器上。
  
  注意,如果我要做并行导出并且将我的 I/O 分布在两个磁盘上,那么我可以对 DUMPFILE 参数值做出修改,并如下添加 PARALLEL 参数和值,如下所示:
  
  DUMPFILE=export_dumps01:gnis%U.dmp,
  
  export_dumps02:gnis%U.dmp
  
  PARALLEL=2
  
  注意,在这个并行导出任务中,目录名作为文件名的一部分来被指定。
  
  检查状态
  
  你可以随时连接到一个运行中的任务来检查其状态。要连接到一个导出任务,必须执行一条 expdp 命令,使用 ATTACH 参数来指定任务名称。 清单 2 显示了到 GNIS_EXPORT 任务的连接。当你连接到一个任务, expdp 显示该任务的相关信息和当前状态,并为你提供一个 EXPORT> 提示符。
  
  当你连接到了一个任务后,你可以随时执行 STATUS 命令查看当前状态,如 清单 3 所示。你还可以执行 CONTINUE_CLIENT 命令返回到显示任务进度的日志输出状态,该命令可以被缩写成如 清单 4 所示的 CONTINUE 。
  
  你可以通过查询 DBA_DATAPUMP_JOBS 视图快速查看所有数据泵任务的状态。你不能获得 STATUS 命令所给出的详细信息,但你可以快速查看到哪些任务在执行、哪些处于空闲状态等。另一个需要了解的视图是 DBA_DATAPUMP_SESSIONS ,它列出了所有活跃的数据泵工作进程。
  
  从故障中恢复
  
  重启动任务的能力使你可以从某些类型的故障中恢复过来。例如, 清单 5 显示了一个用完了转储文件空间的导出任务的日志文件的结尾部分。然而,什么也没有丢失。该任务只是进入了一个空闲状态,当你连接到该任务并查看状态输出时就可以看到这一点。这个状态不显示任务空闲的原因。要确定这是因为转储文件的空间不够了,则你需要查看日志文件。
  
  连接到因转储文件空间不够用了而停止的任务后,你可以在两个操作中选择其一:你可以使用 KILL_JOB 命令来中止该任务,或者增加一个和多个转储文件来继续该任务的运行。如果空间不够的问题是因为磁盘空间不足,则当然你要确保你增加的文件是在另一个有可用空间的磁盘上。你也许需要创建一个新的 Oracle 目录对象来指向这一新位置。
  
  清单 6 使用 ADD_FILES 命令为我的空闲任务增加两个文件。这两个文件位于不同的目录中,它们都不同于为该任务的第一个转储文件所指定的目录。我使用 START_JOB 命令来重新启动该任务,然后使用 CONTINUE 查看屏幕上滚动的其余日志输出。
  
  导入任务不会受到卸载( dump )文件空间不足的影响。但是,它们可能会受到数据表空间不足或无法扩展表空间的影响。导入的恢复过程和导出任务的基本上相同。首先,通过向表空间增加一个数据文件、扩展一个数据文件或其他方法来提供可用空间。然后连接到该任务,执行 START_JOB 命令。导入任务将从它中断的地方继续执行。
  
  导入选定的数据
  
  本文中的例子到目前为止显示的是对用户 GENNICK 拥有的所有对象进行模式( schema )数据库级别的导出。为了展示数据泵的一些新的功能,我要导入那些数据,而且为了使问题更有意思,我列出了以下要求:
  
  仅导入 GNIS 数据表
  将该数据表导入到 MICHIGAN 模式中
  仅导入那些与密歇根州相关的数据行
  不导入原始的存储参数
  
  一开始,我可以在我的导入参数文件中写出以下四行:
  
  DUMPFILE=gnis%U.dmp
  
  DIRECTORY=export_dumps
  
  LOGFILE=gnis_import.log
  
  JOB_NAME=gnis_import
  
  这四行没有什么新意。他们指定了转储文件、目录、日志文件和该任务的名称。根据我们的四个要求,我可以使用 INCLUDE 参数将导入操作限制在我们感兴趣的一个数据表上:
  
  INCLUDE=TABLE:"= 'GNIS'"
  
  INCLUDE 是个很有意思的参数。当你需要导入一个转储文件的部分内容时,你可以有两个方法:
  
  你可以使用一个或多个 INCLUDE 参数列出你要导入的那些对象。
  
  你可以使用 EXCLUDE 参数列出那些你不需要的内容,然后导入其余的内容。
  
  因为我只需要一个对象,明确包含该对象比起明确不包括其它对象要容易得多。我的 INCLUDE 参数值的第一部分是关键字 TABLE ,表明我要导入的对象是一个数据表(其它的可能是一个函数或一个过程)。 接下来是一个冒号,然后是一个 WHERE 子句的谓词。我明确希望数据表名为 GNIS ,所以这个谓词是 "= 'GNIS'" 。如果必要,则你可以写出多个详细的谓词。通过 INCLUDE 和 EXCLUDE 参数,你可以确切地指出以什么样的粒度导入或导出。我建议你仔细地阅读关于这两个参数的文档。它们的功能之强大和多功能性是我在本文中所无法描述的。
  
  我可以很轻松地完成该模式的改变,将来自 GNIS 模式的数据表重新映射到 MICHIGAN 模式:
  
  REMAP_SCHEMA=gennick: michigan
  
  我只需要关于密歇根州的数据行。为此,我可以使用 QUERY 参数来指定一个 WHERE 子句:
  
  QUERY="WHERE gnis_state_abbr='MI'"
  
  QUERY 在老的实用程序中也有,但只能用于导出操作。数据泵使 QUERY 也能用于导入操作,因为数据泵利用了 Oracle 较新的外部数据表功能。只要可能,数据泵会选择直接路径来导出或导入数据,包括从数据库数据文件中读取数据然后直接写到一个导出转储文件中,或读取转储文件然后直接写入数据库数据文件中。但是,当你指定了 QUERY 参数时,数据泵将使用一个外部数据表。对于一个导入任务,数据泵将使用 ORACLE_DATAPUMP 存取驱动程序建立一个外部数据表,并执行一条 INSERT...SELECT...FROM 语句。
  
  我的最后一个要求是避免导入与已被导出的数据表相关的存储参数。我希望 MICHIGAN 模式中的新 GNIS 表沿用该模式的默认表空间的默认存储参数。原因是 MICHIGAN 的默认表空间不足以容纳该数据表的本来大小,但是是以仅仅容纳与密歇根有关的数据行。通过 TRANSFORM 参数,我可以告诉导入任务不要包含与原始表相关的任何数据段属性:
  
  TRANSFORM=SEGMENT_ATTRIBUTES:N
  
  这看起来是件小事,但以前有很多次我都希望老的导入实用程序的 TRANSFORM 参数有这样的功能。我在试图将少量生产数据导入到测试系统中时经常失败,因为即使存储生产数据的各个区段当中许多是空的,其数据量也比我测试系统所能支持的大得多。对于只导入一张数据表的情况,预先建立数据表是解决这个问题的一个办法。然而,随着数据表的增多,预先建表会很麻烦。而 TRANSFORM 这样的简单开关可以轻松地将转储文件中所有数据段的属性全体忽略掉。
  
  将我上面描述的所有选项放到一个参数文件中后,我可以调用导入实用程序,如下所示:
  
  impdp michigan/password
  
  parfile=gnis_import.par
  
  当作为一个没被授权的用户进行导入时,你需要连接到目标模式。如果你拥有 IMP_FULL_DATABASE 角色,那么你可以用自己的身份登录,然后导入到任何目标模式。
  
  性能和多功能性
  
  Oracle 数据泵比起以前的导出和导入实用程序在性能上有很大的提高。这种性能提高大部分来自于读写转储文件的并行操作。你可以指定并行程度来达到你所要求的速度与资源消耗的折中。
  
  下一步
  
  下载本文所使用的示例数据
  
  数据泵还很好地利用了 Oracle 数据库其他最新开发的创新特性。 Flashback (回闪)用于确保导出数据的一致性,而 FLASHBACK_SCN 和 FLASHBACK_TIME 参数使你能够完全控制这一功能。直接路径( direct-path ) API 用于在任何可能的时候提高性能,当直接路径 API 不能使用时,用外部数据表和新的 ORACLE_DATAPUMP 外部数据表存取驱动程序来传输数据。
  
  数据泵除了提供全新的性能外还为你提供灵活性。这表现在 INCLUDE 和 EXCLUDE 参数、 QUERY 参数、 TRANSFORM 参数和其他参数的实现中,这些参数使你能够精细地控制被加载和卸载的数据和对象。
  
  人们一直在不断地对 " 大数据 ?quot; 的含意进行重新定义,这种数据库容量之大在十年前还只能是梦想。在这样的世界里,数据泵对于你的数据库管理员所用的工具库是个不错的补充,使你能够以前所未有的速度对数据库进行数据导入和导出。
  
  Jonathan Gennick ( [email protected] ) 是一名经验丰富的 Oracle 数据库管理员和 Oracle 认证的专家,居住在密歇根州的上部半岛。他在管理着 Oracle 文章电子邮件列表,你可以访问 gennick.com 来了解其中的有关内容。 Gennick 最近参与编写了《 Oracle Regular Expressions Pocket Reference , Oracle 正则表达式袖珍手册》 (O'Reilly & Associates, 2003 出版 ) 一书。
相关内容
赞助商链接