来自农村的老实娃
分类: Oracle
2007-11-27 15:23:54
考虑下面显示的错误:
SQL> conn scott/tiger Connected. SQL> create table t (col1 number); create table t (col1 number) * ERROR at line 1: ORA-01116:error in opening database file 4 ORA-01110:data file 4:'/home/oracle/oradata/PRODB3/users01.dbf' ORA-27041:unable to open file Linux Error:2: No such file or directory Additional information: 3看起来是不是很熟悉?无论您是否做过 DBA,您可能都不止一次地看到过该消息。该错误发生的原因是无法获得特定的数据文件 — 该文件可能已经受损,或者可能有人在数据库运行时删除了该文件。在任何情况下,您都需要在问题的影响范围扩大之前采取一些主动措施。
在 Oracle 数据库 11g 中,新增的 Data Recovery Advisor 极大地简化了该操作。该 Advisor 有两种形式:命令行模式,或者作为 Oracle 企业管理器数据库控制中的一个屏幕。根据具体的情况,每种形式各有其优点。例如,如果您希望通过 shell 脚本自动识别此类文件并通过 cron 或 at 之类的实用程序计划恢复操作,那么选择前者将很有用。对于希望借助 GUI 来指导他们完成该过程的新手 DBA 来说,后一种方法将很有帮助。下面,我将对这两种形式分别进行描述。
命令行选项通过 RMAN 执行。首先,启动 RMAN 进程并连接到目标。
$ rman target=/ Recovery Manager:Release 11.1.0.5.0 - Beta on Sun Jul 15 19:43:45 2007 Copyright (c) 1982, 2007, Oracle.All rights reserved. connected to target database:PRODB3 (DBID=3132722606)假设发生了某个错误,您希望找出原因。使用 list failure 命令可以立即知道答案。
RMAN> list failure;如果没有错误,该命令将返回以下消息:
no failures found that match specification如果有错误,将显示如下更具说明性的消息:
using target database control file instead of recovery catalog List of Database Failures ========================= Failure ID Priority Status Time Detected Summary ---------- -------- --------- ------------- ------- 142 HIGH OPEN 15-JUL-07 One or more non-system datafiles are missing该消息表明某些数据文件已丢失。由于这些数据文件属于 SYSTEM 以外的表空间,因此数据库会挂起,并使该表空间脱机。该错误相当严重,因此优先级设为 HIGH。每个故障都有一个故障 ID,以方便各个故障的识别和解决。例如,您可以发出以下命令来了解故障 142 的详细信息。
RMAN> list failure 142 detail;该命令将向您显示错误的确切原因。
现在,进入了关键部分:如何纠正该错误?经验丰富的 DBA 或许不需要进一步的帮助就可以顺利解决该问题,但是新手 DBA(甚至包括一些有经验但是知识陈旧的 DBA)希望在这里获得一些指导。他们可以向 Data Recovery Advisor 寻求帮助:
RMAN> advise failure;以上命令的响应将对错误进行详细的解释,并说明如何纠正该错误:
List of Database Failures ========================= Failure ID Priority Status Time Detected Summary ---------- -------- --------- ------------- ------- 142 HIGH OPEN 15-JUL-07 One or more non-system datafiles are missing analyzing automatic repair options; this may take some time using channel ORA_DISK_1 analyzing automatic repair options complete Mandatory Manual Actions ======================== no manual actions available Optional Manual Actions ======================= 1. If file /home/oracle/oradata/PRODB3/users01.dbf was unintentionally renamed or moved, restore it Automated Repair Options ======================== Option Repair Description ------ ------------------ 1 Restore and recover datafile 4 Strategy:The repair includes complete media recovery with no data loss Repair script:/home/oracle/app/diag/rdbms/prodb3/PRODB3/hm/reco_3162589478.hm该输出有几个重要部分。首先,该 Advisor 对错误进行了分析。在该案例中,错误很明显:数据文件丢失。接下来,Advisor 建议了一个策略。在该案例中,这也是相当简单的:还原和恢复文件。(请注意,我故意选择了一个简单的示例以便将注意力集中到工具的使用上,而不是讨论数据库可能出现故障的各种情况以及如何恢复。动态性能视图 V$IR_MANUAL_CHECKLIST 也显示了该信息。)
然而,Data Recovery Advisor 执行的最有用的任务却显示在最后一行:它将生成一个可用于修复数据文件或解决该问题的脚本。该脚本可以完成所有工作,您连一行代码都不用编写。
有时,Advisor 无法获取它所需的所有信息。例如,在该案例中,它不知道是有人将文件移到了另一个位置,还是对该文件进行了重新命名。在这种情况下,它会建议将文件移回原来的位置,并恢复原来的名称(在 Optional Manual Actions 下)。
现在,脚本已经准备好了。您准备好执行它了吗?我不了解您的情况,但是我会验证该脚本实际上会首先执行什么。因此,我发出以下命令来“预览”修复任务将执行的操作:
RMAN> repair failure preview; Strategy:The repair includes complete media recovery with no data loss Repair script:/home/oracle/app/diag/rdbms/prodb3/PRODB3/hm/reco_741461097.hm contents of repair script: # restore and recover datafile sql 'alter database datafile 4 offline'; restore datafile 4; recover datafile 4; sql 'alter database datafile 4 online';很好,修复任务似乎在做着和我使用 RMAN 去做的同样的事情。现在,我可以通过发出以下命令来执行实际的修复:
RMAN> repair failure; Strategy:The repair includes complete media recovery with no data loss Repair script:/home/oracle/app/diag/rdbms/prodb3/PRODB3/hm/reco_3162589478.hm contents of repair script: # restore and recover datafile sql 'alter database datafile 4 offline'; restore datafile 4; recover datafile 4; sql 'alter database datafile 4 online'; Do you really want to execute the above repair (enter YES or NO)?假设结果是 OK,我回答 YES,操作将继续执行:
executing repair script sql statement:alter database datafile 4 offline Starting restore at 15-JUL-07 using channel ORA_DISK_1 channel ORA_DISK_1:restoring datafile 00004 input datafile copy RECID=5 STAMP=628025835 file name=/home/oracle/flasharea注意,RMAN 在尝试修复之前如何提示您。如果使用脚本,您可能不希望提示;而是希望继续进行并修复,没有任何提示。如果是这样,只需在 RMAN 提示符下使用 repair failure noprompt 即可。
/PRODB3/datafile/o1_mf_users_39ocxbv3_.dbf destination for restore of datafile 00004:/home/oracle/oradata/PRODB3/users01.dbf channel ORA_DISK_1:copied datafile copy of datafile 00004 output file name=/home/oracle/oradata/PRODB3/users01.dbf RECID=0 STAMP=0 Finished restore at 15-JUL-07 Starting recover at 15-JUL-07 using channel ORA_DISK_1 starting media recovery archived log for thread 1 with sequence 51 is already on disk as file /home/oracle/
flasharea/PRODB3/archivelog/2007_07_15/o1_mf_1_51_39ocxxdw_.arc ... and so on ... name=/home/oracle/flasharea/PRODB3/archivelog/2007_07_15/o1_mf_1_55_39ocy9ox_.arc thread=1 sequence=55 media recovery complete, elapsed time: 00:00:01 Finished recover at 15-JUL-07 sql statement:alter database datafile 4 online repair failure complete RMAN>
知道数据库运行良好并且没有受损块,会让您晚上睡得更好。但是如何才能做到这一点?由于受损块仅在它们被访问时才会暴露出来,因此您希望提前识别它们并可以在用户收到错误消息之前使用简单的命令修复它们。
工具 dbverify 可以完成该工作,但是使用起来可能有点不方便,因为它需要编写一个包含所有数据文件和大量参数的脚本文件。输出还需要扫描和翻译。在 Oracle 数据库 11g 中,RMAN 中的一个新命令 VALIDATE DATABASE 通过检查数据库块中的物理损坏极大地简化了该操作。如果检测到损坏,将记录到自动诊断信息库中。然后,RMAN 将生成输出,下面显示了部分输出:
RMAN> validate database; Starting validate at 09-SEP-07 using target database control file instead of recovery catalog allocated channel:ORA_DISK_1 channel ORA_DISK_1:SID=110 device type=DISK channel ORA_DISK_1:starting validation of datafile channel ORA_DISK_1:specifying datafile(s) for validation input datafile file number=00002 name=/home/oracle/oradata/ODEL11/sysaux01.dbf input datafile file number=00001 name=/home/oracle/oradata/ODEL11/system01.dbf input datafile file number=00003 name=/home/oracle/oradata/ODEL11/undotbs01.dbf input datafile file number=00004 name=/home/oracle/oradata/ODEL11/users01.dbf channel ORA_DISK_1:validation complete, elapsed time: 00:02:18 List of Datafiles ================= File Status Marked Corrupt Empty Blocks Blocks Examined High SCN ---- ------ -------------- ------------ --------------- ---------- 1 OK 0 12852 94720 5420717 File Name:/home/oracle/oradata/ODEL11/system01.dbf Block Type Blocks Failing Blocks Processed ---------- -------------- ---------------- Data 0 65435 Index 0 11898 Other 0 4535 File Status Marked Corrupt Empty Blocks Blocks Examined High SCN ---- ------ -------------- ------------ --------------- ---------- 2 OK 0 30753 115848 5420730 File Name:/home/oracle/oradata/ODEL11/sysaux01.dbf Block Type Blocks Failing Blocks Processed ---------- -------------- ---------------- Data 0 28042 Index 0 26924 Other 0 30129 File Status Marked Corrupt Empty Blocks Blocks Examined High SCN ---- ------ -------------- ------------ --------------- ---------- 3 OK 0 5368 25600 5420730 File Name:/home/oracle/oradata/ODEL11/undotbs01.dbf Block Type Blocks Failing Blocks Processed ---------- -------------- ---------------- Data 0 0 Index 0 0 Other 0 20232 File Status Marked Corrupt Empty Blocks Blocks Examined High SCN ---- ------ -------------- ------------ --------------- ---------- 4 OK 0 2569 12256 4910970 ...或者,如果出现故障,您将在上面的输出部分中看到:...
List of Datafiles ================= File Status Marked Corrupt Empty Blocks Blocks Examined High SCN ---- ------ -------------- ------------ --------------- ---------- 7 FAILED 0 0 128 5556154 File Name:/home/oracle/oradata/ODEL11/test01.dbf Block Type Blocks Failing Blocks Processed ---------- -------------- ---------------- Data 0 108 Index 0 0 Other 10 20您还可以验证特定的表空间:
RMAN> validate tablespace users;或者,验证数据文件:
RMAN> validate datafile 1;或者,还可以验证数据文件中的一个块:
RMAN> validate datafile 4 block 56;但是,VALIDATE 命令的验证范围远远不只是数据文件。您可以验证 spfile、controlfilecopy、恢复文件、快速恢复区,等等。
下面我们来看看企业管理器如何检测和解决故障。
首先,转至 Database 主页,下图显示了该主页的顶部。
RMAN 的应用已经有很长时间了。许多人说他们不使用 RMAN 是因为它相当复杂而且还需要学习语言。但是,在某些情况下,RMAN 是唯一可以完成工作的工具,或者至少是完成工作的最佳工具。考虑一个大型数据文件中只有一个或两个块受损的情况。在这种情况下,无需恢复整个数据文件;您可以执行块媒介恢复来修复受损块。但是如果不使用 RMAN,您可能会遗漏那些隐藏的重要内容。
但是,如果不需要学习语言会是什么样呢?幸运的是,您现在可以通过一个 GUI 访问 RMAN 的所有功能。在本节中,您将了解如何在企业管理器中使用 RMAN 来修复受损块。
在 Database 主页中,单击 Availability 选项卡,如下所示:
在这种情况下,我们不会使用 Data Recovery Advisor,而是执行“User Directed Recovery”以选择所需的恢复过程。User Directed Recovery 部分包含所有必需活动的链接以及在下拉菜单中选择恢复范围的选项,默认情况下,该选项显示 Whole Database。让我们来更加清楚地看看这一部分:
在企业管理器界面中使用 RMAN 做到了两全其美:可以利用 RMAN 的强大功能,又没有了其命令语言的复杂性。RMAN 的高级用户可能不会觉得这多么有用,但是对于新手来说,这却可以在关键时刻帮助他们,尤其是在考虑如何使用一个简单的界面执行相对复杂的块媒介恢复时。
那么,既然这些闪回日志包含块的以前的图像,为什么不将它们也用于恢复呢?Oracle 数据库 11g 正是这么做的。当您恢复特定的块时,Oracle 会在闪回日志(而不是数据文件)中查找该块的以前图像的良好副本,然后应用归档日志以使其向前滚动。由于无需借助备份,该方法可以节省很多时间,尤其是当备份在磁带上时。
RMAN 在 Oracle 数据库 10g 中提供了备份片断压缩功能以节省网络带宽,但是许多人都不轻易使用它。为什么?因为第三方压缩工具提供的方法比 RMAN 自身的更快。但是,RMAN 10g 压缩有一些第三方压缩工具没有提供的好用功能。例如,当 RMAN 10g 恢复数据文件时,它不需要首先解压缩这些文件(如果以前被压缩过)。该方法在还原期间可以显著节省带宽。
在 Oracle 数据库 11g 中,RMAN 提供了另一种算法 ZLIB,而以前使用的是 BZIP2。ZLIB 算法要快得多,但是不能压缩太多内容。另一方面,它也很节省 CPU。因此,如果您的 CPU 不多,最好使用 ZLIB 压缩。(注意,版本 11.1 中的默认选项是 BZIP2;您需要许可一个新选项 Advanced Compression Option 才能使用 ZLIB。)
要使用 ZLIB 压缩,只需将 RMAN 配置参数设置为:
RMAN> configure compression algorithm 'ZLIB' ;如果您以前更改过该参数,需要发出上述命令。要将其更改为 BZIP2,发出以下命令:
RMAN> configure compression algorithm 'bzip2';现在,所有压缩备份都将使用新的算法。
您或许已经知道您可以并行备份,方法是,声明多个通道使每个通道成为一个 RMAN 会话。但是,很少有人意识到每个通道一次只能备份一个数据文件。因此,即使有多个通道,但是每个数据文件只通过一个通道进行备份,这与备份真正并行的概念有些相反。
在 Oracle 数据库 11g RMAN 中,通道可以将数据文件拆分为块,这些块被称为“段”。您可以指定每个段的大小。下面就是一个例子:
RMAN> run { 2> allocate channel c1 type disk format '/backup1/%U'; 3> allocate channel c2 type disk format '/backup2/%U'; 4> backup 5> section size 500m 6> datafile 6; 7> }该 RMAN 命令分配两个通道并在两个通道上并行备份用户的表空间。每个通道占用数据文件的一个 500MB 的段并以并行方式备份该文件。这加快了大型文件的备份速度。
以这种方式备份时,备份的内容也显示为段。
RMAN> list backup of datafile 6; ...注意,备份段是如何显示为文件段的。由于每个段去往不同的通道,因此您可以将它们定义为不同的挂载点(如 /backup1 和 /backup2),您还可以并行方式将它们备份到磁带。... List of Backup Pieces for backup set 901 Copy #1 BP Key Pc# Status Piece Name ------- --- ----------- ---------- 2007 1 AVAILABLE /backup1/9dhk7os1_1_1 2008 2 AVAILABLE /backup2/9dhk7os1_1_1 2009 3 AVAILABLE /backup1/9dhk7os1_1_3 2009 3 AVAILABLE /backup2/9dhk7os1_1_4
但是,如果 6 号大型文件只位于一个磁盘上,则使用并行备份就没有优势了。如果您对该文件进行分段,磁头需要不断移动来处理该文件的不同段,其缺点胜过分段的优点。
您已经知道还原数据的用途。当事务更改某个块时,该块以前的图像将被保存在还原段中。即使事务已提交,数据仍然保存在那里,因为在该块被更改之前启动的某个运行时间较长的查询可能会请求已更改和提交的块。该查询应该获取该块以前的图像,即之前提交的图像而不是当前的图像。因此,即使在提交之后,还原数据仍然保存在还原段中。随着时间的推移,该数据会被冲刷出还原段以便为新插入的还原数据腾出空间。
当 RMAN 备份运行时,它会备份还原表空间中的所有数据。在恢复期间,与提交的事务相关的还原数据将不再需要,因为它们已经在重做日志流中,或者仍然在数据文件中(如果已从缓冲区清除已使用的块并将其磁盘),可以从那里进行恢复。那么,为什么还要备份提交的还原数据呢?
在 Oracle 数据库 11g 中,RMAN 很智能:它不备份恢复所不需要的已提交还原数据。而对备份至关重要的未提交还原数据照常备份。这减少了备份(以及恢复)的大小和时间。
在许多数据库中,尤其是在事务提交更加频繁,还原数据在还原段中的存留时间更长的 OLTP 数据库中,大多数还原数据实际上已被提交。因此,RMAN 只需备份还原表空间中的几个块。
最好的是,您不需要做任何事即可实现该优化,Oracle 会自行操作。
您可能会使用一个目录数据库作为 RMAN 信息库。如果没有,您应该认真地考虑使用一个目录数据库。这有很多优点,例如报告、控制文件受损时简化恢复,等等。
现在,又出现了一个问题:多少个目录合适?通常,只创建一个目录数据库作为所有数据库的信息库是合理的。但是,要考虑到安全性,这可能不是一个好方法。目录拥有者将能够查看所有数据库的所有信息库。由于每个要备份的数据库可能都有一个单独的 DBA,因此不应该让该目录可见。
那么,还有什么别的方法吗?当然,您可以为每个目标数据库都创建一个单独的目录数据库,可是考虑到成本,这或许不太实际。另一种方法是仍然只创建一个目录数据库,但是为每个目标数据库都创建一个虚拟目录。虚拟目录是 Oracle 数据库 11g 中的新增功能。让我们看看如何创建虚拟目录。
首先,您需要创建一个包含所有目标数据库的基础目录。假设拥有者为“RMAN”。从目标数据库,以基础用户身份连接到目录数据库并创建目录。
$ rman target=/ rcvcat rman/rman@catdb Recovery Manager:Release 11.1.0.6.0 - Production on Sun Sep 9 21:04:14 2007 Copyright (c) 1982, 2007, Oracle.All rights reserved. connected to target database:ODEL11 (DBID=2836429497) connected to recovery catalog database RMAN> create catalog; recovery catalog created RMAN> register database; database registered in recovery catalog starting full resync of recovery catalog full resync complete
这称为基础目录,由用户“RMAN”拥有。现在,让我们再创建两个将拥有各自的虚拟目录的用户。为简单起见,我们让这两个用户的名称与目标数据库相同。仍然以基础目录拥有者 (RMAN) 的身份保持连接,同时发出以下语句:RMAN> grant catalog for database odel11 to odel11; Grant succeeded.现在,使用虚拟目录拥有者 (odel11) 的身份连接,并发出 create virtual catalog 语句:
$ rman target=/ rcvcat odel11/odel11@catdb RMAN> create virtual catalog; found eligible base catalog owned by RMAN created virtual catalog against base catalog owned by RMAN现在,在同一 RMAN 信息库中注册另一个数据库 (PRONE3),并为其同名数据库创建一个虚拟目录拥有者“prone3”。
RMAN> grant catalog for database prone3 to prone3; Grant succeeded. $ rman target=/ rcvcat prone3/prone3@catdb RMAN> create virtual catalog; found eligible base catalog owned by RMAN created virtual catalog against base catalog owned by RMAN现在,如果您希望查看已注册的数据库,以基础目录拥有者 (RMAN) 的身份连接,您将看到:
$ rman target=/ rcvcat=rman/rman@catdb RMAN> list db_unique_name all; List of Databases DB Key DB Name DB ID Database Role Db_unique_name ------- ------- ----------------- --------------- ------------------ 285 PRONE3 1596130080 PRIMARY PRONE3 1 ODEL11 2836429497 PRIMARY ODEL11按照预期,它显示了两个注册的数据库。现在,以 ODEL11 的身份连接并发出同一命令:
$ rman target=/ rcvcat odel11/odel11@catdb RMAN> list db_unique_name all; List of Databases DB Key DB Name DB ID Database Role Db_unique_name ------- ------- ----------------- --------------- ------------------ 1 ODEL11 2836429497 PRIMARY ODEL11注意如何只列出一个数据库,而不是两个全列出。该用户 (odel11) 只允许查看一个数据库 (ODEL11),即上面显示的数据库。您可以通过以另一个拥有者 PRONE3 的身份连接到目录对此进行验证:
$ rman target=/ rcvcat prone3/prone3@catdb RMAN> list db_unique_name all; List of Databases DB Key DB Name DB ID Database Role Db_unique_name ------- ------- ----------------- --------------- ------------------ 285 PRONE3 1596130080 PRIMARY PRONE3利用虚拟目录,您可以仅为 RMAN 信息库目录维护一个数据库,但要建立安全边界以使各个数据库拥有者管理其自己的虚拟信息库。一个通用的目录数据库可以简化管理、降低成本以及在提高数据库可用性的同时降低成本。
仍然是多个目录这个主题,让我们来考虑另外一个问题。既然您已经了解如何在相同的基础目录上创建虚拟目录,您可能看到了将所有这些独立的信息库整合到一个信息库中的必要性。
一个选择是在各自的目录中取消目标数据库的注册,然后将它们重新注册到新的中央目录。但是,这样做意味着会丢失存储在这些信息库中的所有有价值的信息。当然,您可以同步控制文件,然后再重新同步到目录,但是这样会使控制文件变得很大,而且不实际。
Oracle 数据库 11g 提供了一个新特性:合并目录。实际上,该功能是将目录从一个数据库导入另一个数据库,或者换句话说,就是“移动”目录。
我们来看一下它的工作原理。假设您希望将目录从数据库 CATDB1 移到另一个名为 CATDB2 的数据库中。首先,连接到目录数据库 CATDB2(目标):
$ rman target=/ rcvcat rman/rman@catdb2 Recovery Manager:Release 11.1.0.6.0 - Production on Sun Sep 9 23:12:07 2007 Copyright (c) 1982, 2007, Oracle.All rights reserved. connected to target database:ODEL11 (DBID=2836429497) connected to recovery catalog database如果该数据库已经有一个用户“RMAN”拥有的目录,那么转至下一导入步骤;否则,您将需要创建该目录:
RMAN> create catalog; recovery catalog created现在,从远程目录 (catdb1) 导入:
RMAN> import catalog rman/rman@catdb1; Starting import catalog at 09-SEP-07 connected to source recovery catalog database import validation complete database unregistered from the source recovery catalog Finished import catalog at 09-SEP-07 starting full resync of recovery catalog full resync complete上面的输出中有一些重要信息。注意,目标数据库如何取消了在其原始目录数据库中的注册。现在,如果您检查这个新目录中的数据库名称:
RMAN> list db_unique_name all; List of Databases DB Key DB Name DB ID Database Role Db_unique_name ------- ------- ----------------- --------------- ------------------ 286 PRONE3 1596130080 PRIMARY PRONE3 2 ODEL11 2836429497 PRIMARY ODEL11您将注意到 DB Key 已更改。ODEL11 以前为 1,现在为 2。
上面的操作会将所有已注册的目标数据库的目录导入目录数据库。有时,您可能不希望这样,而只希望导入一个或两个数据库。要进行以上操作,可以发出以下命令:
RMAN> import catalog rman/rman@catdb3 db_name = odel11;这会再次更改 DB Key。
如果您不希望在导入期间取消导入数据库在源数据库中的注册,该如何操作呢?换句话说,您希望让数据库在两个目录数据库中都有注册。您将需要使用“no unregister”子句:
RMAN> import catalog rman/rman@catdb1 db_name = odel11 no unregister;这将确保数据库 ODEL11 不会在目录数据库 catdb1 中取消注册,同时又在新的目录中进行了注册