数据库文件损坏与坏块处理_第1页
数据库文件损坏与坏块处理_第2页
数据库文件损坏与坏块处理_第3页
数据库文件损坏与坏块处理_第4页
数据库文件损坏与坏块处理_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、数据库文件损坏与坏块处理作者:徐聪目录控制文件损坏处理:3一:对于在非归档模式下的数据库:4二:对于在归档模式下的数据库:5Redo文件损坏处理:6一:非current redo损坏6二:current redo损坏6Undo文件损坏处理:7方法一:使用system segment8方法二:跳过损坏的segment9DATAFILE坏块处理11一:什么是数据库的坏块11二:坏块对数据库产生的影响11三:坏块产生的原因11四:坏块的处理方法12五:坏块的预先发现的方法14在数据库日常使用中,我们经常会遇到各种各样的坏块。在不同文件中或不同对象中的损坏或坏块有着不同的处理方式。控制文件损坏处理:控

2、制文件遇到坏块时,基本现象就是控制文件的损坏,数据库无法启动到MOUNT,当然一般数据库都有多个控制文件组成。如果遇到其中的一个或者几个控制文件损坏(不是全部控制文件损坏),那么我们可以通过修改pfile中的control file初始化参数去除损坏的控制文件,或者复制未损坏的控制文件来覆盖损坏的控制文件,来达到修复控制文件的目的。如果遇到所有的控制文件损坏(没有做任何备份的情况下),那么就要我们手工来创建控制文件。手工创建控制文件脚本列子如下(需要数据库在nomount下):CREATE CONTROLFILE REUSE DATABASE "orcl" RESETLOG

3、S NOARCHIVELOG MAXLOGFILES 16 MAXLOGMEMBERS 3 MAXDATAFILES 100 MAXINSTANCES 8 MAXLOGHISTORY 292LOGFILE GROUP 1 '/oradata/orcl/redo01.log' SIZE 256M, GROUP 2 '/oradata/orcl/redo02.log' SIZE 256M, GROUP 3 '/oradata/orcl/redo03.log' SIZE 256MDATAFILE '/oradata/orcl/SUPHISV3.

4、dbf', '/oradata/orcl/SUPHISV301.dbf', '/oradata/orcl/SUPHISV302.dbf', '/oradata/orcl/SUPHISV303.dbf', '/oradata/orcl/SUPHISV304.dbf', '/oradata/orcl/SUPHISV305.dbf', '/oradata/orcl/SUPHISV3CJ.dbf', '/oradata/orcl/SUPHISV3CJ01.dbf', '/or

5、adata/orcl/SUPHISV3CJ02.dbf', '/oradata/orcl/SUPHISV3CJ03.dbf', '/oradata/orcl/SUPNCIS.dbf', '/oradata/orcl/SUPNCIS2011.dbf', '/oradata/orcl/supncis01.dbf', '/oradata/orcl/supncis02.dbf', '/oradata/orcl/supncis03.dbf', '/oradata/orcl/supncis04.

6、dbf', '/oradata/orcl/supncis05.dbf', '/oradata/orcl/supncis06.dbf', '/oradata/orcl/supncis07.dbf', '/oradata/orcl/supncis08.dbf', '/oradata/orcl/sysaux01.dbf', '/oradata/orcl/system01.dbf', '/oradata/orcl/undotbs01.dbf', '/oradata/orcl/

7、users01.dbf'CHARACTER SET ZHS16GBK;注意上面脚本中标红的位置需要重点关注来进行修改。orcl为数据库的SIDNORESETLOGS/RESETLOGS为是否要重置redo log文件NOARCHIVELOG/ARCHIVELOG为数据库是否在归档模式CHARACTER SET ZHS16GBK为数据库的字符集关于是否要重置redo需要根据具体情况进行判断:一:对于在非归档模式下的数据库:1) 当redo log文件为未损坏时,使用noresetlogs noarchivelog此时,当完成控制文件的创建后,直接使用alter database moun

8、t;alter database open;可以直接打开数据库。2) 当redo log文件也同样损坏,使用resetlogs noarchivelogalter database mount; alter system set "_allow_resetlogs_corruption"=true scope=spfile;   -这个参数是关键,可以允许Oracle重置REDO日志recover database until cancel;  -使用CANCEL退出,运行后才可以使用resetlogs去open数

9、据库alter database open resetlogs;二:对于在归档模式下的数据库:1) 所有的online logs好的情况下,使用noresetlogs archvelogalter database mount;alter system switch log all;alter database open;2) 如果online logs损坏,使用resetlogs archivelog对于至少有一个有效归档存在的环境(RAC必须每个节点都有至少一个归档)recover database using backup controlfile until cancle; -根据提示输

10、入所需的归档文件的全路径alter database open resetlogs;对于没有归档存在的环境下alter database mount; alter system set "_allow_resetlogs_corruption"=true scope=spfile;   -这个参数是关键,可以允许Oracle重置REDO日志recover database until cancel;  -使用CANCEL退出,运行后才可以使用resetlogs去open数据库alter database open

11、resetlogs;在上述各个情况下做完打开数据操作后,不要忘记添加temp表空间和做一次数据库全备。当然可能还会遇到一些其他的报错信息,那么久需要对具体问题具体分析了。Redo文件损坏处理:使用命令查看损坏的redo log是不是当前的redo log,使用如下命令:select group#,sequence#,archived,status from v$log;一:非current redo损坏可进行删除,和重新添加的操作(注意至少有2组redo log文件),如:ALTER DATABASE DROP LOGFILE GROUP 3;Alter database add logfil

12、e thread 1 group 3 (/oradata/orcl/redo03.log) size 256M;二:current redo损坏1) 如果有归档和备份,可以用不完全恢复startup mount;recover database until cancel;  -先选择auto,尽量恢复可以利用的归档日志,然后重新执行:recover database until cancel; -这次输入cancel,完成不完全恢复,用resetlogs打开数据:alter database open resetlogs; -打开数据库 2) 强制恢复,

13、这种方法可能会导致数据不一致startup mount;alter system set "_allow_resetlogs_corruption"=true scope=spfile;recover database until cancel; -使用命令cancelalter database open resetlogs;一般强制恢复恢复后会有undo segment的问题。一般操作为重建undo表空间,该步骤可在undo损坏中看到。Undo文件损坏处理:Oracle 的undo 有两种管理方式,通过参数undo_management来设置auto

14、 和 manual。 1)  当undo_management被设置成MENUAL时使用系统回滚段, 即将undo records 记录到SYSTEM 表空间下的SYSTEM段。 SQL> select segment_name,tablespace_name,bytes,next_extent  from dba_segments where segment_type='ROLLBACK' SEGMENT_NA TABLESPACE_NAME 

15、;      BYTES NEXT_EXTENT- - - -SYSTEM     SYSTEM                 393216     1048576        通过上面

16、的这条语句,我们查到了这个用于rollback 的system segment 存在与system 表空间。 默认情况下,只有一个segment,并且它还比较小,所以,如果使用system段来存储undo records。肯定会影响数据库的性能。 所以Oracle 是建议使用Undo tablespace 来管理undo records。 2) 当undo_management设置成AUTO时使用UNDO tablespace来管理回滚段。 这个时候,我们将有多个undo segment,并且这些segm

17、ent 是存放在UNDO 表空间里的。 这样对DB的性能就会提高。 SQL> select segment_name,tablespace_name,bytes,next_extent  from dba_segments where segment_type='TYPE2 UNDO' SEGMENT_NAME    TABLESPACE_NAME    BYTES NEXT_EXTENT- - - -_SYSSM

18、U1$            UNDOTBS1                1179648       65536_SYSSMU2$         

19、0;  UNDOTBS1                1179648       65536_SYSSMU3$            UNDOTBS1      

20、60;         2228224       65536_SYSSMU4$            UNDOTBS1                1179

21、648       65536_SYSSMU5$            UNDOTBS1                 262144       65536_SYSSM

22、U6$            UNDOTBS1                1179648       65536_SYSSMU7$         

23、0;  UNDOTBS1                1179648       65536_SYSSMU8$            UNDOTBS1      

24、60;         1179648       65536_SYSSMU9$            UNDOTBS1                1179

25、648       65536_SYSSMU10$           UNDOTBS1                1179648       65536通过以上SQL的查询结果,我们可

26、以看出,有10个undo segment来存放undo records。        以上我们是通过dba_segment 表查看的结果。 也可以通过v$rollstat和v$rollname 两个视图来查看信息。 这2个视图会显示所有rollback 段的信息。 包括system段和undo段。 SQL> col name format a15SQL> select s.usn,,s.extents,s.hwmsize

27、,s.status from v$rollstat s, v$rollname n where s.usn=n.usn;        USN NAME               EXTENTS    HWMSIZE STATUS- - - - -      

28、0;  0 SYSTEM                   6     385024 ONLINE         1 _SYSSMU1$         &

29、#160;      3    7659520 ONLINE         2 _SYSSMU2$                3    9691136 ONLINE   &#

30、160;     3 _SYSSMU3$                4    7462912 ONLINE         4 _SYSSMU4$         &

31、#160;      3   76668928 ONLINE         5 _SYSSMU5$                4    8511488 ONLINE    &

32、#160;    6 _SYSSMU6$                3    7462912 ONLINE         7 _SYSSMU7$          

33、      3   33480704 ONLINE         8 _SYSSMU8$                3    8577024 ONLINE     

34、    9 _SYSSMU9$                3    7462912 ONLINE        10 _SYSSMU10$           

35、60;   3   13754368 ONLINE 11 rows selected. 3) UNDO 损坏的情况 出现这种情况,大多数是因为异常宕机,在启动的时候报的错误。DB 不能启动。       比如:ORA-00600: internal error code, arguments: 4194,         

36、60;对于Undo 损坏的情况,能用备份恢复最好,如果不能,就只能通过一些特殊的方法来恢复。 方法一:使用system segment步骤如下:(1)用spfile 创建pfile,然后修改参数:#*.undo_tablespace='UNDOTBS1'#*.undo_management='AUTO'#*.undo_tablespace#*.undo_retentionundo_management='MANUAL'rollback_segments='SYSTEM' (2)用修改之后的p

37、file,重启DBSQL> STARTUP MOUNT pfile='/oracle/product/10.2.0/dbs/initorcl.ora' ; (3)删除原来的表空间,创建新的UNDO 表空间SQL> drop tablespace undotbs;SQL> create undo tablespace undotbs1 datafile '/u01/oradata/undotbs1.dbf' size 10M; (4)关闭数据库,修改pfile参数,然后用新的pfile创建spfile,在正常启动数据

38、库。*.undo_tablespace='UNDOTBS1'*.undo_management='AUTO'#undo_management='MANUAL'#rollback_segments='SYSTEM'   方法二:跳过损坏的segment       在方法一里面,使用了system segment。undo segment 一般有多个,我们可以通过alert log 来查看正在使用的是哪些segme

39、nt,这些段有可能损坏了。那么只需要把这些损坏的segment 跳过,先正常启动DB,在创建新的UNDO 表空间,在切换一下。 (1)修改pfile,添加参数:*._corrupted_rollback_segments='_SYSSMU11$','_SYSSMU12$','_SYSSMU13$' 这些字段的值,我们通过alert log 查看。 也可以通过如下命令查看:#strings system01.dbf | grep _SYSSMU | cut -d $ -f 1 | sort

40、 -u (2)用修改之后的pfile启动DB       因为跳过了哪些损坏的segment,所以DB 可以正常启动。 (3)创建新的UNDO 表空间,并切换过来 SQL> create undo tablespace undotbs1 datafile '/u01/oradata/undotbs1.dbf' size 10M;SQL> alter system set undo_tablespace=undotbs1;SQL> drop t

41、ablespace undotbs; (4)修改pfile,创建spfile,并正常启动删除:*._corrupted_rollback_segments='_SYSSMU11$','_SYSSMU12$','_SYSSMU13$'SQL> select segment_name,status from dba_rollback_segs ; -查看rollback_segment此时回滚段状态为offline,现在都可以删除了:SQL> drop rollback segment "_SYSSMU11$"

42、; ;SQL> drop rollback segment "_SYSSMU12$" ;SQL> drop rollback segment "_SYSSMU13$" ;  DATAFILE坏块处理一:什么是数据库的坏块数据库的数据块有固定的格式和结构,分三层:cache layer,transaction layer,data layer。对数据块进行读取写入操作的时候,数据库会对要读写的数据块做一致性的检查,其中包括:数据块的类型、数据块的地址信息、数据块的SCN号以及数据块的头部和尾部。如果发现其中有不一致的信息,那

43、数据库就会标记这个数据块为坏块了。数据库的坏块分为两种,逻辑坏块和物理坏块。 二:坏块对数据库产生的影响 如果数据库出现坏块,数据库的告警日志文件里面会存在有如下的一些报错信息:Ora-1578以及Ora-600 and trace file in bdump directory,其中Ora-600错误的第一个参数值的范围是2000-8000,不同的值代表着数据块的不同的层出现问题,具体的如下表所示:Range              

44、;     block layerCache layer              2000 4000Transaction layer        4000 6000Data layer             &#

45、160; 6000 - 8000坏块产生影响的对象可能是数据字典表、回滚段表、临时段、用户数据表和索引等。不同的对象产生坏块后的处理方法不尽相同。三:坏块产生的原因Oracle调用标准C的系统函数,对数据块进行读写操作,因此,坏块是有可能由以下几种原因产生:硬件的I/O错误操作系统的I/O错误或缓冲问题内存或paging问题磁盘修复工具一个数据文件的一部分正在被覆盖Oracle试图访问一个未被格式化的系统块失败数据文件部分溢出Oracle或者操作系统的bug 四:坏块的处理方法1) 先收集相应的关于坏快的信息,从AlertSID.log文件或者从trace文件中查找,找到例如以下的一

46、些信息:  Ora-1578  file#  (RFN)  block#Ora-1110  file#  (AFN)  block#  Ora-600   file#  (AFN)  block#其中RFN表示的是relative_fnoAFN表示的是file_id        Select file_na

47、me,tablespace_name,file_id “AFN”,relative_fno “RFN”       From dba_data_files;        Select file_name,tablespace_name,file_id, relative_fno“RFN”        From dba_temp_files;2)  确定存在坏块的对

48、象是什么:    SELECT tablespace_name, segment_type, owner, segment_name, partition_name  FROM dba_extents WHERE file_id = <AFN> and <BL> between block_id AND block_id + blocks 1;    通过上面这个查询语句就可以查出当前存在坏块的对象是什么,是什么类型的对象。需要注意的是如果是temp文件中出现坏块,是没有

49、记录返回的。3)  根据2)中查询出来的对象类型,确定相应的处理方法出现坏块的常见对象有:sys用户下的对象回滚段临时段索引或者分区索引表常用的处理方法有:恢复数据文件只恢复坏的block(9i以上版本可用)通过ROWID RANGE SCAN 保存数据使用DBMS_REPAIR使用EVENT4)  具体处理方法的介绍Ø         恢复数据文件方法:如果数据库是归档方式下,并且有完整的物理备份,就可以使用此方法来恢复。步骤如下:(1)  &

50、#160;    先offline受影响的数据文件,执行以下的语句:    ALTER DATABASE DATAFILE 'name_file' OFFLINE;(2)       保留有坏块的数据文件,然后拷贝备份的数据文件。如果恢复的数据文件要求路径不同,执行以下的语句:    ALTER DATABASE RENAME FILE 'old_name' TO '

51、new_name'(3)       恢复数据文件,执行以下语句:    RECOVER DATAFILE 'name_of_file'(4)       Online恢复后的数据文件,执行以下的语句:ALTER DATABASE DATAFILE 'name_of_file' ONLINE;Ø      &

52、#160;只恢复坏的block(9i以上版本可用)   使用这种方法要求数据库版本是9.2.0以上,要求配置了Rman的catalog数据库,数据库为归档方式,并且有完整的物理备份。   步骤如下:   使用RMAN的BLOCKRECOVER命令 :   Rman>runblockrecover datafile 5 block 11,16;   也可以强制使用某个SCN号之前的备份,恢复数据块。   Rman

53、>runblockrecover datafile 5 block 11,16 restore until sequence 8505;Ø       通过ROWID RANGE SCAN 保存数据1)    先取得坏块中ROW ID的最小值,执行以下的语句:   SELECT dbms_rowid.rowid_create(1,<OBJ_ID>,<RFN>,<BL>,0) from DUAL;

54、2)取得坏块中的ROW ID的最大值,执行以下的语句:   SELECT dbms_rowid.rowid_create(1,<OBJ_ID>,<RFN>,<BL>+1,0) from DUAL;3)建议一个临时表存储那些没有坏块的数据,执行以下的语句:   CREATE TABLE salvage_table AS SELECT  *   FROM  corrupt_tab Where 1=2;4)保存那些不存在坏块的数据到临时

55、表中,执行以下的语句:   INSERT INTO salvage_table SELECT /*+ ROWID(A) */ * FROM <owner.tablename> A WHERE rowid < '<low_rid>';INSERT INTO salvage_table SELECT /*+ ROWID(A) */ * FROM <owner.tablename> A  WHERE rowid >= '<hi_rid>'5) 根据临

56、时表中的数据重建表,重建表上的索引,限制。Ø       使用10231诊断事件,在做全表扫描的时候跳过坏块可以在session级别设定:ALTER SESSION SET EVENTS '10231 TRACE NAME CONTEXT FOREVER, LEVEL 10'也可以在数据库级别上设定,在初始化参数中加入:event="10231 trace name context forever, level 10" ,然后重启数据库。然后从存在坏块的表中取出不存在坏

57、块的数据,执行以下的语句:CREATE TABLE salvage_emp AS SELECT * FROM corrupt_table;最后rename生成的corrupt_table为原来表的名字,并重建表上的索引和限制。Ø       使用dbms_repair包进行恢复   使用dbms_repair标记有坏块的表,在做全表扫描的时候跳过坏块,执行以下的语句:Execute DBMS_REPAIR.SKIP_CORRUPT_BLOCKS('<schema>&

58、#39;,'<tablename>');然后使用导入导出工具或者createtable as select的方法取出没有坏块数据,然后重建表,表上的索引和限制。 五:坏块的预先发现的方法1) 如果要检测数据库中所有的表,可以利用exp工具导出整个数据库可以检测坏块。不过这个工具有一些缺陷,对以下情况的坏块是检测不出来的: HWM以上的坏块是不会发现的Ø  索引中存在的坏块是不会发现的Ø  数据字典中的坏块是不会发现的2) 如果只是对数据库中比较重要的表进行坏块检查,可以使用ANALYZE

59、 TABLE tablename VALIDATE STRUCTURE CASCADE 的方法来检测坏块,它执行坏块的检查,但是不会标记坏块为corrupt,检测的结果保存在USER_DUMP_DEST目录下的用户trace文件中。3)  使用Oracle的专门工具dbv来检查坏块,具体的语法如下:关键字     说明                    (默认)-FILE        要验证的文件

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论