Chinaunix首页 | 论坛 | 博客
  • 博客访问: 447789
  • 博文数量: 135
  • 博客积分: 4177
  • 博客等级: 上校
  • 技术积分: 1145
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-13 17:16
文章分类

全部博文(135)

文章存档

2011年(5)

2010年(4)

2009年(26)

2008年(25)

2007年(29)

2006年(42)

2005年(4)

分类: Oracle

2007-03-01 23:34:28

随着办公自动化和电子商务的飞速发展,企业对信息系统的依赖性越来越高,数据库作为信息系统的核心担当着重要的角色。尤其在一些对数据可靠性要求很高的行业如银行、证券、电信等,如果发生意外停机或数据丢失其损失会十分惨重。为此数据库管理员应针对具体的业务要求制定详细的数据库备份与灾难恢复策略,并通过模拟故障对每种可能的情况进行严格测试,只有这样才能保证数据的高可用性。数据库的备份是一个长期的过程,而恢复只在发生事故后进行,恢复可以看作是备份的逆过程,恢复的程度的好坏很大程度上依赖于备份的情况。此外,数据库管理员在恢复时采取的步骤正确与否也直接影响最终的恢复结果,本文主要针对Oracle数据库可能遇到的各种故障提供了相应的恢复的方法,仅供大家参考。

要对Oracle数据库备份与恢复有清晰的认识,首先有必要对数据库的几种运行状态有充分的了解。Oracle数据库的运行状态主要分为3种,他们依次为:

l Nomount(非安装)Oracle只是读取ini文件中的配置信息,并初始化SGA区。

l Mount(安装)Oracle除了需要读取ini文件还要读取控制文件,并从中获取有关数据库的物理结构等信息。

l Open(打开)数据库要检查所有文件处于同一时间点,对错误进行恢复对未完成事务回滚,并最终可以允许用户访问。

数据库的备份主要分为三种类型:冷备份;热备份;逻辑备份;

数据库的备份不是本文讨论的重点,在这里只作一个概要的介绍,Oracle数据库备份主要有:

l Cold Backup(冷备份) 主要指在关闭数据库的状态下进行的数据库完全备份,备份内容包括所有数据文件、控制文件、联机日志文件、ini文件。

l Hot Backup(热备份) 指在数据库处于运行状态下,对数据文件和控制文件进行备份,要使用热备份必须将数据库运行在(Archive Log)归档方式下。

l Export(逻辑备份)这是最简单的备份方法,可按数据库中某个表、某个用户或整个数据库来导出,并且支持全部、累计、增量三种方式。使用这种方法,数据库必须处于打开状态,而且如果数据库不是在restrict状态将不能保证导出数据的一致性。

数据库的恢复可分为两大类:完全恢复;不完全恢复;

完全恢复指将数据库恢复到发生故障的时间点,不丢失任何数据。不完全恢复指将数据库恢复到发生故障前的某一个时间点,此时间点以后的所有改动将会丢失。如果没有特殊需求,我们建议应尽量使用完全恢复。

Oracle数据库的恢复过程分两步进行,首先将把存放在重做日志文件中的所有重做运用到数据文件,之后对重做中所有未提交的事务进行回滚,这样所有数据就恢复到发生灾难那一时刻了。数据库的恢复只能在发生故障之前的数据文件上运用重做,将其恢复到故障时刻,而不能将数据文件反向回滚到之前的某一个时刻。举个例子,我们有一个2001/1/1的数据库备份,当2001/5/1使我们发现数据库中数据发生混乱,希望将数据库恢复到2001/4/30时的状态,我们只能先恢复2001/1/1的数据库备份然后在其上运用重做记录使其前滚到2001/4/30时的状态,而不能将2001/5/1的数据库向后回滚到2001/4/30。

为了系统的设计数据库的恢复方案,我们先对可能遇到的错误进行分类,Oracle数据库错误主要分为5大类:

l SQL语句失败

l 线程失败

l 实例失败

l 用户操作失败

l 存储设备失败

如果发生前三种失败,不需要我们人为干涉,Oracle系统会自动进行恢复。对于用户操作型的失败(如误删除数据),我们采取的补救措施主要有导入最新的逻辑备份或进行到某一时间点的不完全恢复。从Oracle 8之后的新版本中引入了基于表空间的时间点恢复(TSPITR),可以单独将包含错误操作的表空间恢复到指定时间,而不必对整个数据库进行不完全恢复。当错误操作发现比较及时而且数据量不大的情况下也可以考虑使用logminer生成反向SQL。

针对存储设备的失败的情况比较复杂也是本文讨论的重点,存储设备的失败必然会使放置在其上的文件变为不可用,我们先将Oracle数据库所涉及到的文件进行一个划分,主要可分为:

l Oracle的系统文件,指Oracle的运行文件,各种应用程序

l 数据库控制文件

l 数据库联机重做日志文件

l 数据文件

l 归档日志文件

避免第一种文件失败主要依赖系统管理员进行操作系统级的备份,当发生事故后只能依靠操作系统备份将其恢复。

控制文件中记录着整个数据库的结构、每个数据文件的状况、系统SCN、检查点计数器等重要信息,在创建数据库时会让用户指定三个位置来存放控制文件,他们之间互为镜像,当其中任何一个发生故障,只需将其从ini文件中注释掉故障数据文件就可重新将数据启动。当所有控制全部失效时,可以在Nomount模式下执行create controlfile来重新生成控制文件,但必须提供redo log,data file,文件名和地址以及MAXLOGFILES,MAXDATAFILES,MAXINSTANCES等信息。如果失败之前运行过alter database backup controlfile to trace或alter database backup controlfile to ‘xxx’对控制文件作备份,恢复时可使用生成的脚本来重建或用备份文件覆盖,如果使用了旧的控制文件在恢复时要使用recover xxx using backup controlfile选项来进行恢复,并使用resetlogs选项来打开数据库。

如果丢失的是联机日志文件,分两种情况处理1、丢失的是非活动的日志文件;2、丢失的是当前激活的日志文件。

如果是第一种情况,而发生故障的日志文件组又具有多个成员,可以先将数据库shutdown,然后用操作系统命令将损坏日志文件组中好的日志成员文件把损坏的成员文件覆盖(在同一个日志成员组中的所有日志文件的各为镜象的),如果其物理位置不可用可将其拷贝到新的驱动器上,使用alter database rename file ‘xxxx’ to ‘xxxx’改变文件位置,之后启动数据库,如果正常马上进行一个冷备份。如果损坏的日志组中只有一个日志成员,先mount上数据库,将其转换为noarchivelog模式,执行alter database add logfile member ‘xxx’ to group ‘x’给相关组增加一个成员,再执行alter database drop logfile member ‘bad_file’将损坏的日志文件删除,由于数据库的结构发生变动需要备份控制文件,之后将数据库改回archivelog模式,做一个冷备份。

如果丢失的是当前激活的日志文件,数据库又没有镜像而且当前日志组中所有成员均变为不可用。首先将数据库shutdown abort,从最近的一次全备份中恢复所有的数据文件,将数据库启动到mount状态。如果原来的日志文件物理位置不可用,使用alter database rename file ‘xxx’ to ‘xxx’改变文件的存放位置。然后,使用recover database until cancel命令来恢复数据库,直到提示最后一个归档日志运用完之后,输入cancel。之后用alter database open resetlogs打开数据库,如果没有问题,立即进行一个冷备份。注意!所有包含在损坏的redo log中的信息将会丢失,也就是说数据库崩溃前已经提交的数据有可能会丢失。这对于某些要求很高的应用将会损失惨重,因此应尽量使每个日志组具有多个日志成员,并且放置在不同的驱动器上一防止发生介质故障。

数据文件发生故障的情况也分为多种情况,1、丢失包含在SYSTEM表空间的数据文件;2、丢失没有回滚段的非SYSTEM数据文件;3、丢失有回滚段的非SYSTEM数据文件。

如果损坏的是系统表空间的数据文件。唯一的办法是从上一次备份中恢复受损的数据文件,(如果原位置不可用使用alter database rename命令改变新文件的位置),之后在数据库mount的状态下执行recover database/datafile对数据库进行回复,才能将数据库打开。注意:当SYSTEM表空间或其中的数据文件脱机,数据库是无法被打开的,因此必须在mount状态下将所有的恢复工作完成。

当丢失的数据文件不属于系统表空间而且也不包含回滚段时,有可选择在数据库的两种状态下进行恢复---在数据库open的状态或者在数据库mount的状态。如果用户急于访问数据库中未受损部分的数据或对损坏的数据文件进行恢复需要很长时间,可以先使受损的数据文件脱机,将数据库打开给用户访问,再恢复受损的数据文件最后将其联机。步骤如下:先在数据库mount时,将相关的数据文件或表空间进行脱机alter database datafile xxx offline,然后将数据库open,这样就能使数据库未受损的部分先供用户访问,之后再进行recover datafile/tablespace,完成后用alter database datafile/tablespace ‘xxx’ online使其恢复联机就可被访问了。 当然用户也可以选择在数据库mount状态下,用recover database/datafile将所有的恢复工作做完,将所有数据文件一起打开供用户访问。

如果丢失的数据文件是最后一种情况,即包含有回滚段的非系统表空间数据文件。也可以选择是在数据库先open的状态还是在mount状态下恢复。不过与上一种情况不同的是当包含回滚段的数据文件损坏时,如果使其先offline将数据库打开,那么所有数据库崩溃前未提交的事务涉及到的表将无法访问,也就是说在回滚段恢复前其中涉及的对象都不允许被访问。而且当所有包含回滚段的数据文件都在offline状态时,数据库无法进行任何DML操作,因此在数据库open状态恢复包含回滚段的数据文件时,可以先创建几个临时回滚段供数据使用create rollback segment temp1 tablespace system; alter rollback segment temp1 online;,当数据文件恢复后再将他们删除alter rollback segment temp1 offline; drop rollback segment temp1;。注意:当用这种方法使恢复的数据文件online之后,所有的原有回滚段将处于offline状态,必须手工使用alter rollback segment RBSxx online;使他们恢复联机状态,这样才能被数据库正常使用。如果在数据库mount状态下完成所有恢复,则不需要上述步骤。

如果丢失数据文件后,用户发现没有故障前的数据文件的备份,而且自从丢失的数据文件最早建立之后一直没有使用过resetlogs选项打开过数据库。也就是说用户的控制文件是在损坏的数据文件建立前创建的,归档日志中包括对损坏数据文件的所有重做记录。用户就还有一种恢复方法,用户可以先将损坏的数据文件或表空间脱机alter database datafile / tablespace xxx offline,之后执行alter database create datafile ‘new/xxx.dbf’ as ‘old/xxx.dbf’,数据库会根据保存在控制文件中的信息重建一个空的数据文件,之后再执行recover tablespace / datafile将所有重做记录运用到数据文件,使其完全恢复到当前状态,之后便可再将其恢复联机。

如果丢失的是最后一种文件---归档文件或归档文件所处的物理位置不可用,首先shutdown数据库,立即作一个冷备份。然后修改ini文件中的归档日志文件目的路径,重新启动数据库。以后再发生灾难只需从最新的备份中将相关文件恢复,数据库作recover时就不需要备份之前丢失的归档文件了。在Oracle 8之后的新版本中提供了log_archive_duplex_dest和log_archive_dest_1...5等参数允许保留多份归档文件到不同位置,甚至到远端服务器从而保证归档文件的可靠性。

最后再说几点数据库恢复时的注意事项:

1.本文讨论所有情况的默认前提是数据库运行在归档(ARCHIVELOG)方式下,并只涉及到一般常见的情况和最基本的恢复方法。使用Oracle提供的恢复管理器RMAN也能完成上述任务,如果运行环境比较复杂建议使用RMAN来做备份和恢复。

2.一旦数据库发生灾难,最好在进行恢复之前做一次完全的冷备份,以便在进行恢复时产生差错还可以进行补救。很大一部分数据丢失是由于不正确的恢复操作所引起的。

3.当数据库完成恢复之后,尤其是使用resetlogs选项打开数据库之后,要马上关闭数据库进行一次完全的冷备份。因为,为防止放弃的重做日志被下次恢复时再次运用,resetlogs选项会重新创建redo log文件并将其的计数清零,这将使之前做的所有备份将变为不可用(一般情况下)。

4.要特别注意当进行数据库完全恢复,从发生故障的时间点前的备份中恢复损坏文件时,一定不要使备份中的redo log文件覆盖了当前的redo log文件,否则就只能进行不完全恢复并且要丢失一部分数据了。


==================================
[原创]一次ORACLE的恢复过程:没有归档。

  Oracle数据库恢复文档:

毕照杰(广州)

2003-12-25日,客户数据库因为掉电,数据库不能正常启动。

故障现象:
进入应用程序的时候,提示:Oracle startup or shutdown in progress.....


诊断及解决过程:
1、SVRMGR> startup nomount;
  没有问题

2、SVRMGR> alter database mount;
出现在以下内容,乱码:
alter database mount
*
ORA-00214: ???? 'D:\ORACLE\ORADATA\ORACLE\CONTROL02.CTL' ?? 16788 ??? 'D:\ORACLE
\ORADATA\ORACLE\CONTROL01.CTL' ?? 16780 ???

3、为了解决这个乱码,先设置字符集,然后再重新来过一次:
SVRMGR> shutdown abort;
SVRMGR> exit;
c:\set nls_lang=american_america.zhs16gbk
SVRMGR> startup nomount;

4、SVRMGR> alter database mount;
出现以下内容,诊断是几个控制文件版本不一致:
alter database mount
*
ORA-00214: controlfile 'D:\ORACLE\ORADATA\ORACLE\CONTROL02.CTL' version 16788 in
consistent with file 'D:\ORACLE\ORADATA\ORACLE\CONTROL01.CTL' version 16780

解决方法:
打开init.ora,找到
control_files = ("d:\oracle\oradata\oracle\control01.ctl", "d:\oracle\oradata\oracle\control02.ctl", "d:\oracle\oradata\oracle\control03.ctl")
把它修改为:
control_files = ("d:\oracle\oradata\oracle\control02.ctl", "d:\oracle\oradata\oracle\control03.ctl")
去掉其中的第一个控制文件。

5、
SVRMGR>shutdown abort;
SVRMGR>startup nomount;
SVRMGR>alter databse mount;
SVRMGR>alter databse open;

这时出现这样的内容:
alter database open
*
ORA-00314: log 3 of thread 1, expected sequence# 3990 doesn't match 3987
ORA-00312: online log 3 thread 1: 'D:\ORACLE\ORADATA\ORACLE\REDO01.LOG'

诊断,log日志版本不对。

尝试以下操作,均告失败:
SVRMGR> alter database open resetlogs;
出现以下错误:
alter database open resetlogs
*
ORA-01139: RESETLOGS option only valid after an incomplete database recovery

SVRMGR> alter database open noresetlogs;
出现以下错误:
alter database open noresetlogs
*
ORA-01139: RESETLOGS option only valid after an incomplete database recovery

SVRMGR> recover database until time '2003-12-24:19:19:19';
出现以下错误:
ORA-01547: warning: RECOVER succeeded but OPEN RESETLOGS would get error below
ORA-01194: file 1 needs more recovery to be consistent
ORA-01110: data file 1: 'D:\ORACLE\ORADATA\ORACLE\SYSTEM01.DBF'

SVRMGR> alter database open resetlogs;
出现以下错误:
alter database open resetlogs
*
ORA-01194: file 1 needs more recovery to be consistent
ORA-01110: data file 1: 'D:\ORACLE\ORADATA\ORACLE\SYSTEM01.DBF'

6、
使用ORACLE数据库的部分数据恢复方式。
它的主要做法就是不检查数据库的一致性,来打开数据库,虽然会造成数据的不准确和丢失,
但是还是可以保存在大部分数据的。

做法:

打开init.ora,添加一行文字:
_allow_resetlogs_corruption=true

然后再进行以下操作:
SVRMGR>shutdown abort;
SVRMGR>startup mount;
SVRMGR>recover database until cancel
此时数据库提示
SVRMGR> recover database until cancel;
ORA-00279: change 3684318 generated at 12/30/2003 10:55:34 needed for thread 1
ORA-00289: suggestion : D:\ORACLE\ORA81\RDBMS\ARC00001.001
ORA-00280: change 3684318 for thread 1 is in sequence #1
Specify log: {=suggested | filename | AUTO | CANCEL}

输入 cancel,这时出现这样的信息:
ORA-01547: warning: RECOVER succeeded but OPEN RESETLOGS would get error below
ORA-01194: file 1 needs more recovery to be consistent
ORA-01110: data file 1: 'D:\ORACLE\ORADATA\ORACLE\SYSTEM01.DBF'

SVRMGR>alter database open noresetlogs;

提示:
Statement processed.

这时,数据库已经起来了。
此时,要尽快把数据库导出来。

exp system/manager file=c:\oracle.dmp full=y ...


在数据库恢复的过程中,多谢 zp_ccc、rockey 、水皮皮 、lgqducky 等各位大侠的帮助。在这里一并谢过了!!!
[此贴子已经被作者于2003-12-30 12:28:01编辑过]

========================================================
数据库一致性检查失败,oracle不能open。[原创]

  机器异常断电,oracle不能正常启动,可以mount,不能open。数据库未备份过。
错误码:
At startup, the database will mount, but gives the following errors at open:
ORA-00312: "online log %s thread %s: '%s'"
     Cause: This message reports the filename for details of another message.
    Action: Other messages will accompany this message. See the
            associated messages for the appropriate action to take.
ORA-00322: "log %s of thread %s is not current copy"
     Cause: Check of log file header at database open found that an online log  
            appears to be an incorrectly restored backup.
    Action: Restore correct file or reset logs.

解决方法描述:
首先检查ORACLE_HOME 和ORACLE_SID在startup参数中是否正确,如果不正确重新startup。

Recover the loss of an inactive, online redo log group.

SQL>ALTER DATABASE CLEAR LOGFILE 'filename';

If there is more than one LOGFILE in the redo log group then you must
specify all the log files.

For example, the following fails:

SVRMGR> alter database clear logfile '/vobs/oracle/dbs/log3.log';
alter database clear logfile '/vobs/oracle/dbs/log3.log'
*
ORA-1514: error in log specification: no such log
ORA-1517: log member: '/vobs/oracle/dbs/log3.log

But, specifying all the log files in the group works:
SVRMGR> ALTER DATABASE CLEAR LOGFILE ('/vobs/oracle/dbs/t4.log','/vobs/oracle/;
Statement processed.

介绍一个意外情况,如果上面的方法不成功,数据库还是不能open,采用recover,restore都不成功,说明logfile可能已经损坏,数据库打开需要做一致性检查,所以不能正常打开。因为数据库未作过备份,为了尽可能地减少损失,采用打开数据库,然后立刻导出数据的方法。
oracle有一个不推荐的方法,可以使数据库在不进行一致性检查的方式下打开数据库。
做法:
1。为保险起见,将数据库的系统表空间,数据文件,控制文件均做一次备份:copy。
2。在初始化配置文件中(init.ora)加上:
_allow_resetlogs_corruption=true
_corrupted_rollback_segments=(将所有rollback_segments=(...)的内容加到这里)
将rollback_segments=(...)前加上#
3。startup mount
recover database until cancel;
cancel
alter database open resetlogs;
此时数据库已经可以打开了,请立刻将数据export出来,然后重新安装oracle,重新建立database,再将数据import。
注意:这种方法属于数据库的不完全恢复,最后提交的sql可能会丢失,毕竟能够尽可能地减少损失,可以试试。
以上操作我均做过测试。

logminer使用方法[转帖]

  logminer使用方法

前一段时间我想查询数据库中一个表的纪录的最后修改时间,大家给我提出了很多方法,其中logminer我觉得是比较好的一种,就找了些帮助文档,并进行了研究测试,下面公布一下使用过程,以及期间碰到的问题和解决方法,跟大家共享。其中oracle home的路径大家自己根据我的路径进行修改。
1:介绍:dbms_logmnr是oracle在oracle8i所提供的新package。它主要用于分析log file文件(包括online redo log file,archived log file),将log file中的信息转存到v$logmnr_contents中,从而获取对oracle数据库操作的历史信息。它不仅可以分析oracle8i的log file,也可以分析oracle8的log file。信息主要包括在你分析的时间限制内数据库数据作了些什么变更,执行了哪些语句。
2:使用方法
      1)打开init.ora文件,加入utl_file_dir=d:\oracle(注:改为自己的路径,是logminer使用文件的默认路径),然后应用新的设置打开oracle数据库。
       2)执行SQL>。 execute dbms_logmnr_d.build('shwdict.ora','D:\oracle'); ,(注:将生成d:\oracle\shwdict.ora文件,此文件可以以后重复使用,但不能同时用于几个logmnr)用于生成数据字典;如果没有dbms_logmnr_d包,需手工执行@d:\oracle\ora8\rdbms\admin\dbmslmd.sql;如果执行过程中报下标越界错误,则需要打开@d:\oracle\ora8\rdbms\admin\dbmslmd.sql文件,将其中的TYPE col_desc_array IS VARRAY(513) OF col_description的513加大,我是改成了1513,保存文件重新执行@d:\oracle\ora8\rdbms\admin\dbmslmd.sql;(注:都要以sysdba身份登陆执行)。
     3)将要分析的日志文件加入要分析的log list中,察看有哪些日志文件可以用select * from v$logfile;查询已经加入那些可以用select * from v$logmnr_logs(注:查询必须在同一个会话中查询,单独开查询将查不到)语句如下:execute dbms_logmnr.add_logfile('d:\oracle\oradata\shw\redo01_1.log',dbms_logmnr.new);
execute dbms_logmnr.add_logfile('d:\ORACLE\ORADATA\ORA\REDO02_1.LOG',dbms_logmnr.addfile);
execute dbms_logmnr.add_logfile('d:\ORACLE\ORADATA\ORA\REDO03_1.LOG',dbms_logmnr.addfile);
如果需要从分析列表里去掉一个文件用
('d:\ORACLE\ORADATA\ORA\REDO03_1.LOG',dbms_logmnr.removefile);      
       4)更改会话时间表达方式(注一定要在本会话下修改,我开始发生错误就是因为在别的会话里修改的,如果允许,可以将数据库默认的时间表达方式修改掉)会话内修改为alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; 系统设置在注册表。
       5)查询分析的日志文件包含的scn范围和日期范围。
select low_time,high_time,low_scn,next_scn from v$logmnr_logs;会列出你加入的日志文件的以上信息。
    6)执行分析:
dbms_logmnr.start_logmnr(
    dictfilename => 'd:\oracle\shwdict.ora',startscn=>xxxxxx,endscn=>xxxxx,starttime => to_date('20030501 12:15:00','yyyymmdd hh24:mi:ss'), endtime => to_date('20030501 15:40:30','yyyymmdd hh24:mi:ss'));
要注意scn范围和日期格式,格式要与你修改的一样。
    7:查询
Select SCN,timestamp, session# session_num, sql_redo
From V$LOGMNR_CONTENTS
Order by 1
具体要查询什么内容可以自己修改。
有问题或错误请指正,我会予以修改,希望对大家有用!
阅读(1792) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~