ORACLE坏块(ORA-01578)处理方法
- 格式:docx
- 大小:20.04 KB
- 文档页数:11
ORA-01578: Oracle data block corrupted (file # f_num, block # b_num)产生原因:当ORACLE访问一个数据块时,由于1、硬件的I/O错误;2、操作系统的I/O错误或缓冲问题;3、内存或paging问题;4、ORACLE试图访问一个未被格式化的系统块失败;5、数据文件部分溢出等上述几种情况的一种引起了逻辑坏块或者物理坏块,这时就会报ORA-01578的错误。
解决方式:由于ORACLE只有在访问到有问题的数据文件时才会报错,所以报错的时间有可能会比实际出错的时间要晚,如果ORA-01578出错信息提示数据坏块指向的是用户自己的数据文件,则用以下方法来解决:如果通过下面的SQL语句查出的坏块出现有索引上,则只需重建索引即可SQL>Select owner, segment_name, segment_type from dba_extents where file_id=5 and block_id between 60474 -1 and 60474如果坏块出现在表上,先用以下语句分析是否为永久性坏块(建议多执行一两次,有助于鉴别数据坏块是永久性的(硬盘上的物理坏块)还是随机性的(内存或硬件错误引起)):SQL>Analyze table validate structure cascade;执行该命令后,可能会出现以下的结果:ORA-01578:与原先错误信息有相同的参数,为永久性的物理或逻辑坏块;如果与原先错误信息有不同的参数,可能与内存,page space和I/O设备有关。
如果用户有此表的最新备份,那么最好是用此备份来恢复此表,或者使用event 10231来取出坏块以外的数据:<1>.先关闭数据库<2>.编辑init.ora文件,加入:event=”10231 trace name context forever,level 10”<3>.startup restrict<4>.创建一个临时表:SQL>create table errortemp as select * from error ;(error是坏表的表名)<5>.把event从init.ora文件中删掉并重起数据库<6>.rename坏表,把临时表rename成坏表的表名<7>.创建表上的INDEX等如果ORA-01578出错信息提示数据坏块指向的是数据字典或者是回滚段的话,你应该立即与ORACLE公司联系,共同商量一个好的解决办法。
ORACLE坏块(ORA-01578)模拟与处理方法一。
.什么是数据库的坏块首先我们来大概看一下数据库块的格式和结构——数据库的数据块有固定的格式和结构,分三层cache layer,transaction layer,data layer。
在我们对数据块进行读取写入操作的时候,数据库会对要读写的数据块做一致性的检查,其中包括数据块的类型、数据块的地址信息、数据块的SCN号以及数据块的头部和尾部。
如果发现其中有不一致的信息,那数据库就会标记这个数据块为坏块了。
数据库的坏块分为两种,逻辑坏块和物理坏块。
二.模拟坏块SQL> conn systemSQL> create tablespace corrupt datafile 'C:\corrupt.dbf' size 200k;SQL> create table corrupt_tab tablespace corrupt as select * from all_users;SQL> alter table corrupt_tab modify(user_id primary key);SQL> select extent_id,file_id,block_id,blocks from dba_extents2 where owner='SYSTEM' and segment_name='CORRUPT_TAB';EXTENT_ID FILE_ID BLOCK_ID BLOCKS---------- ---------- ---------- ----------0 8 17 8上述查询说明,这个表具有一个区间EXTNET_ID 0,位于8号文件,从块号17开始,大小为8个块。
SQL> conn / as sysdbaSQL> shutdown immediate;用UE编辑器模拟出物理或逻辑坏块。
Oracle 坏块总结收藏Oracle数据库出现坏块现象是指:在Oracle数据库的一个或多个数据块(一个数据块的容量在创建数据库时由db_block_size参数指定,缺省为8K)内出现内容混乱的现象。
由于正常的数据块都有固定的合法内容格式,坏块的出现,导致数据库进程无法正常解析数据块的内容,进而使数据库进程报错乃至挂起,并级联导致整个数据库实例出现异常。
一.坏块的产生原因坏块产生的原因大致有以下几种:1.1 硬件问题Oracle进程在处理一个数据块时,首先将其读入物理内存空间,在处理完成后,再由特定进程将其写回磁盘;如果在这个过程中,出现内存故障,CPU计算失误,都会导致内存数据块的内容混乱,最后反映到写回磁盘的数据块内容有误。
同样,如果存储子系统出现异常,数据块损坏也就随之出现了。
1.2 操作系统BUG由于Oracle进程对数据块的读写,都是以操作系统内核调用(system call)的方式完成的,如果操作系统在内核调用存在问题,必然导致Oracle进程写入非法的内容。
1.3 操作系统的I/O错误或缓冲问题1.4 内存或paging问题Oracle软件BUGOracle软件特定版本上,可能出现导致数据块的内容出现异常BUG。
1.5 非Oracle进程扰乱Oracle共享内存区域如上文所述,在当数据块的内容被读入主机的物理内存时,如果其他非Oracle进程,对Oracle 使用的共享内存区域形成了扰乱,最终导致写回磁盘的数据块内容混乱。
1.6 异常关机,掉电,终止服务异常关机,掉电,终止服务使进程异常终止,而破坏数据块的完整性,导致坏块产生。
注:这也是为什么突然断电会导致数据库无法启动由上可见,坏块的形成原因复杂。
当出现坏块时,为了找到确切的原因,需要大量的分析时间和排查操作,甚至需要多次重现才能找出根本原因。
但当故障发生在生产系统上,我们为了减少停机时间,会尽快实施应急权变措施以保证系统的可用性,这样就破坏了故障现场,对根本原因的分析因而也更加困难了。
一个安静的下午,测试环境中一台装有ORACLE数据库的AIX小机因意外断电而导致其上的oracle数据库宕机了。
由于是测试环境,安排了一个工程师过去解决了,具体是这样解决的:首先重启了小机服务器,启动完后,发现oracle所在的/app目录没有mount上。
然后通过smitty fs修复了一下,mount上了app,再接着启动oracle就起来了。
事后搜集了system.txt 系统日志(通过errpt -a获得)和alert_soa.log以及oracle的跟踪日志trc,分析trc日志看到如下:/app/oracle/product/10.2.0/admin/soa/bdump/soa_mmon_307366.trcOracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options ORACLE_HOME = /app/oracle/product/10.2.0System name: AIXNode name: data2Release: 3Version: 5Machine: 00CE993C4C00Instance name: soaRedo thread mounted by this instance: 1Oracle process number: 11Unix process pid: 307366, image: oracle@data2 (MMON)*** 2013-03-01 14:06:10.308*** SERVICE NAME:(SYS$BACKGROUND) 2013-03-01 14:06:10.212*** SESSION ID:(161.1) 2013-03-01 14:06:10.212Hex dump of (file 3, block 49259)Dump of memory from 0x07000000C5934000 to 0x07000000C59360007000000C5934000 06A20000 00C0C06B 0178F614 00000104 [.......k.x......]7000000C5934010 45A30000 010A0025 0000224D 0178F614 [E......%.."M.x..]7000000C5934020 00000000 1F023200 00C0C069 00010003 [......2....i....]又观察另两个文件,发现有较多ORA-1578报错和DISK OPERATION ERROR。
ORACLE数据库数据恢复、性能优化来问问ASKMACLEAN【转】处理Oracle 7/8/8i/9i/10g/11g 中的数据块损坏/讹误/坏块适用于:Oracle Database – Enterprise Edition –版本7.0.16.0 到11.2.0.2.0 [发行版7.0 到11.2]本文档所含信息适用于所有平台用途本文章讨论如何处理Oracle 数据文件中的一个或多个坏块,并介绍了处理这些坏块的主要方法。
在采取任何措施之前,请先阅读完整篇文章。
详细信息文档历史记录本文中所提到的所有SQL 语句均适用于SQL*Plus(8.1 或更高版本),或作为SYSDBA 用户连接时,适用于Server Manager (Oracle7/8.0)。
(例如:―connect / as sysdba‖或―connect internal‖)简介本文章讨论如何处理Oracle 数据文件中的一个或多个坏块,并介绍了处理这些坏块的主要方法。
在采取任何措施之前,请先阅读完整篇文章。
本文档未介绍内存坏块问题(通常为ORA-600 [17xxx] 类型错误)。
注意:如果在启动时出现ORA-1578 问题,请与当地支持中心联系,以获得参考建议。
Doc 106638.1 –本文档不会提供给客户,但其中的相关步骤可以由经验丰富的支持分析人员提供。
本文章介绍了许多类型的错误,很多其他地方也可能引用到本文章。
重要的是,您需要知道关于每个坏块的以下信息:包含坏块的文件的绝对文件编号(FILE NUMBER)。
本文中称为―&AFN‖。
包含坏块的文件的名称。
本文中称为―&FILENAME‖。
(如果您知道文件编号,但不知道文件名,则可以使用V$DATAFILE 来获取文件名:SELECT name FROM v$datafile WHERE file#=&AFN;如果文件号未显示在Oracle8i 的V$DATAFILE 中,且&AFN 大于DB_FILES 参数值,则该文件可能是临时文件。
Oracle坏块故障总结最近处理了两次典型的ora-01578,ora-01115,ora-01110故障,一次是平湖索引块坏,一次是黄山数据文件坏、blob数据块坏。
平湖的警告日志文件中有以下信息:ORA-12012: error on auto execute of job 21ORA-01578: ORACLE data block corrupted (file # 10, block # 2558610) ORA-01110: data file 10: 'D:\ORACLE\ORADATA\BS\USERS04.DBF'ORA-12012: error on auto execute of job 1ORA-01578: ORACLE data block corrupted (file # 16, block # 2624066) ORA-01110: data file 16: 'D:\ORACLE\ORADATA\BS\USERS10.DBF'应用软件可以正常使用,偶尔会报错ora-01578。
排错过程登录数据库检查:select count(*) from ep_table t where ptime<trunc(sysdate)-30 andalarmtype=0784163select count(*) from ep_table t4281062看来全表扫描正常select from ep_table t where ptime<trunc(sysdate)-31 and ptime>trunc(sysdate)-33 and alarmtype=0 and rownum<10001索引扫描报错了,推断为索引上有坏块!继续查:select owner,file_id,segment_name, segment_type, block_id, blocks from dba_extentswhere file_id=16 and block_id<=2624066 and (block_id + blocks- 1) >= 2624066;运气真好重建相关索引后数据库就恢复了。
ORACLE坏块(ORA-01578)处理方法文章分类:数据库0.模拟出现坏块环境SQL> CREATE TABLESPACE "TEST"2 LOGGING3 DATAFILE 'D:\ORACLE\ORADATA\ALAN\TEST.ora' SIZE 1M EXTENT4 MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO5 /表空间已创建。
SQL> create user alantest identified by alantest2 default tablespace test3 temporary tablespace temp;用户已创建SQL> grant dba to alantest;授权成功。
SQL> connect alantest/alantest已连接。
SQL> show userUSER 为"ALANTEST"SQL> create table test_alan as select * from dba_objects;RMAN> backup database format='c:\rmanbackup\FULL_%U';启动 backup 于 07-7月 -06正在使用目标数据库控制文件替代恢复目录分配的通道: ORA_DISK_1通道 ORA_DISK_1: sid=18 devtype=DISK通道 ORA_DISK_1: 正在激活 full 数据文件备份集通道 ORA_DISK_1: 正在指定备份集中的数据文件在备份集中包含当前的 SPFILE备份集中包括当前控制檔输入数据文件 fno=00001 name=D:\ORACLE\ORADATA\ALAN\SYSTEM01.DBF输入数据文件 fno=00002 name=D:\ORACLE\ORADATA\ALAN\UNDOTBS01.DBF 输入数据文件 fno=00003 name=D:\ORACLE\ORADATA\ALAN\INDX01.DBF输入数据文件 fno=00005 name=D:\ORACLE\ORADATA\ALAN\USERS01.DBF输入数据文件 fno=00004 name=D:\ORACLE\ORADATA\ALAN\TOOLS01.DBF输入数据文件 fno=00006 name=D:\ORACLE\ORADATA\ALAN\CATTAB01.DBF输入数据文件 fno=00007 name=D:\ORACLE\ORADATA\ALAN\TEST.ORA通道 ORA_DISK_1: 正在激活段 1 于 07-7月 -06通道 ORA_DISK_1: 已完成段 1 于 07-7月 -06段 handle=C:\RMANBACKUP\FULL_0JHNJ63P_1_1 comment=NONE通道 ORA_DISK_1: 备份集已完成, 经过时间:00:01:38完成 backup 于 07-7月 -06SQL> shutdown immediate数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
使用编辑工具修改数据文件生成坏块C:\>dbv file=D:\ORACLE\ORADATA\ALAN\TEST.ora blocksize=8192DBVERIFY: Release 9.2.0.6.0 - Production on 星期五 7月 7 14:53:46 2006 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.DBVERIFY - 验证正在开始 : FILE = D:\ORACLE\ORADATA\ALAN\TEST.ora标记为损坏的页12***Corrupt block relative dba: 0x01c0000c (file 7, block 12)Bad check value found during dbv:Data in bad block -type: 6 format: 2 rdba: 0x01c0000clast change scn: 0x0000.0007bc14 seq: 0x1 flg: 0x04consistency value in tail: 0xbc140601check value in block header: 0x91ea, computed block checksum: 0x110e spare1: 0x0, spare2: 0x0, spare3: 0x0***DBVERIFY - 验证完成检查的页总数:128处理的页总数(数据):77失败的页总数(数据):0处理的页总数(索引):0失败的页总数(索引):0处理的页总数(其它):16处理的总页数 (段) : 0失败的总页数 (段) : 0空的页总数:34标记为损坏的总页数:1汇入的页总数:0Highest block SCN : 506930 (0.506930)1.对相关的表进行操作:SQL> select * from alantest.test_alan where rownum=1234;select * from alantest.test_alan where rownum=1234*ERROR 位于第 1 行:ORA-01578: ORACLE 数据块损坏(文件号7,块号12)ORA-01110: 数据文件 7: 'D:\ORACLE\ORADATA\ALAN\TEST.ORA'SQL> select count(*) from alantest.test_alan;select count(*) from alantest.test_alan*ERROR 位于第 1 行:ORA-01578: ORACLE 数据块损坏(文件号7,块号12)ORA-01110: 数据文件 7: 'D:\ORACLE\ORADATA\ALAN\TEST.ORA'2. 检查alter.log出现的报错信息Corrupt block relative dba: 0x01c0000c (file 7, block 12)Bad check value found during buffer readData in bad block -type: 6 format: 2 rdba: 0x01c0000clast change scn: 0x0000.0007bc14 seq: 0x1 flg: 0x04consistency value in tail: 0xbc140601check value in block header: 0x91ea, computed block checksum: 0x91a spare1: 0x0, spare2: 0x0, spare3: 0x03. 确定坏块的对象是什么?SQL> select tablespace_name,segment_type,segment_name,owner fromdba_extents2 where file_id=7 and 12 BETWEEN block_id AND block_id+blocks-1; TABLESPACE_NAME SEGMENT_TYPE SEGMENT_NAME OWNERTEST TABLE TEST_ALAN ALANTESTa. file# block# 可以从错误信息中得到b. 如果是temp檔中出现坏块是没有记录返回的c. 通常容易出现坏块的对象有:数据字典(system表空间) 回滚段临时段联机日志索引或者分区索引表4. 如果通过返回的结果确定坏的是索引段只要把这个索相删除然后重建一下就可以了如果出现坏的是表段请继续往下看5. 具体解决办法A. 恢复数据文件方法前提要求:a.数据库为归档方式b.有完整的物理备份步骤:(1) offline受影响的数据文件执行以下的语句:ALTER DATABASE DATAFILE 7 OFFLINE;(2) 把旧的数据文件保存后移除(3) 恢复数据文件执行以下语句:RESTORE DATAFILE 7;RECOVER DATAFILE 7;(4) Online恢复后的数据文件执行以下的语句:ALTER DATABASE DATAFILE 7 ONLINE;B.只恢复坏的block(9i以上版本可用)前提要求:a.要求数据库版本是9.2.0以上b.数据库为归档方式c.有完整的物理备份步骤:(1) 使用RMAN的BLOCKRECOVER命令:Rman>run{blockrecover datafile 7 block 12;}RMAN> blockrecover datafile 7 block 12;启动 blockrecover 于 07-7月 -06正在使用目标数据库控制文件替代恢复目录分配的通道: ORA_DISK_1通道 ORA_DISK_1: sid=16 devtype=DISK通道 ORA_DISK_1: 正在恢复块通道 ORA_DISK_1: 正在指定要从备份集恢复的块正在恢复数据文件 00007 的块通道 ORA_DISK_1: 已从备份段 1 恢复块段 handle=C:\RMANBACKUP\FULL_0JHNJ63P_1_1 tag=TAG20060707T132408params=NULL通道 ORA_DISK_1: 块恢复已完成正在开始介质的恢复完成介质的恢复完成 blockrecover 于 07-7月 -06可以强制使用某个SCN号之前的备份来恢复数据块Rman>run{blockrecover datafile 7 block 12 restore until sequence 8505; }C.通过ROWID RANGE SCAN 保存资料步骤:(1) 通过file# block# 查出出现坏块的objectSQL> select tablespace_name,segment_type,segment_name,owner fromdba_extents2 where file_id=7 and 12 BETWEEN block_id AND block_id+blocks-1; TABLESPACE_NAME SEGMENT_TYPE SEGMENT_NAME OWNERTEST TABLE TEST_ALAN ALANTEST(2) 构造坏块的ROWIDSQL> SELECT DATA_OBJECT_ID FROM dba_objects whereobject_name='TEST_ALAN' and owner='ALANTEST';DATA_OBJECT_ID--------------6627SQL> SELECT dbms_rowid.rowid_create(1,6627,7,12,0) from DUAL;DBMS_ROWID.ROWID_C------------------AAABnjAAHAAAAAMAAASQL> SELECT dbms_rowid.rowid_create(1,6627,7,13,0) from DUAL;DBMS_ROWID.ROWID_C------------------AAABnjAAHAAAAANAAAOracle的物理扩展ROWID有18位每位采用64位编码分别用A~Z、a~z、0~9、+、/共64个字符表示A表示0,B表示1,……Z表示25,a表示26,……z表示51,0表示52,……,9表示61,+表示62,/表示63 .ROWID具体划分可以分为4部分。