如何格式化不属于任何段的损坏块 (文档 ID 1526163.1)

如何格式化不属于任何段的损坏块 (文档 ID 1526163.1)



类型:
状态:
上次主更新:
上次更新:
语言:
PROBLEM
PUBLISHED
2015-9-8
2015-10-27
English简体中文日本語???

文档内容

症状
原因
解决方案
参考

适用于:

Oracle Database - Enterprise Edition - 版本 8.1.7.4 到 11.2.0.1.0 [发行版 8.1.7 到 11.2]
本文档所含信息适用于所有平台

症状

1. Rman 备份失败,显示 ORA-19566 错误,且被报告的坏块不属于任何对象
2. Dbverify 显示存在坏块
3. 坏块不属于任何对象

原因

在重新使用和重新格式化坏块之前,RMAN 和 DBV 仍会一直报告坏块。

解决方案

免责声明:本说明中给出的步骤并不总是保证问题解决。

解决此类问题的一个可能的方法如下。请注意,它不能保证问题解决,但它已知解决了几种案例的问题。如果在某个数据文件中报告有很多块损坏,请在第六步提示输入 blocknumber 中输入已经报告的最高的坏块号码。

当一个对象被重新创建,已经分配给它(甚至是损坏的块)的块将变成空闲空间(free space)。他们在那里等待重新分配到一个需要额外空间的对象。一旦它们被重新分配到用于一个对象上新的extent,只有当任何DML操作使用到这些块(即使损坏的块,处在空闲空间,现在需要被分配),他们将在DML操作更改、使用这些块之前,被重新格式化掉。

需要注意的是extent的简单的分配不格式化块。第7步分配的extent和第8步执行DML操作,使用在第七步中分配的块,这样的坏块才被重用和格式化。

 

在本文档中,我们尝试手动重新格式化坏块。

第 1 步 - 确定损坏的数据文件

损坏可以被报告在应用层,如DBV和RMAN,或alert.log。

例如,您可以在您的RMAN备份过程中获得以下信息:

RMAN-03009: failure of backup command on nm4501 channel at 04/29/2005 09:44:41

ORA-19566: exceeded limit of 0 corrupt blocks for file E:\xxxx\test.ORA.

 

坏块位于文件 E:\xxxx\test.ORA 中。

 

 

第 2 步 - 在受影响的数据文件上运行 DBV/Rman 验证并检查坏块

在报告坏块的数据文件上运行 dbverify。

# dbv userid={system/password} file={full path filename} logfile={output filename}

检查{输出文件名}结果

示例输出:

    DBVERIFY: Release 9.2.0.3.0 - Production on Thu Aug 25 11:15:54 2005
    Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

DBVERIFY - Verification starting : FILE = E:\xxxx\test.ORA Page 48740 is marked corrupt    ***

 Corrupt block relative dba: 0x01c0be64 (file 7, block 48740)
 Bad check value found during dbv:

  Data in bad block -

  type: 0 format: 2 rdba: 0x0000be64
  last change scn: 0x0000.00000000 seq: 0x1 flg: 0x05
  consistency value in tail: 0x00000001
  check value in block header: 0xb964, computed block checksum: 0x2a5a
  spare1: 0x0, spare2: 0x0, spare3: 0x0
  ***

 DBVERIFY - Verification complete

  Total Pages Examined         : 64000
  Total Pages Processed (Data) : 0
  Total Pages Failing   (Data) : 0
  Total Pages Processed (Index): 1751
  Total Pages Failing   (Index): 0
  Total Pages Processed (Other): 45
  Total Pages Processed (Seg)  : 0
  Total Pages Failing   (Seg)  : 0
  Total Pages Empty            : 62203
  Total Pages Marked Corrupt   : 1

请注意,在数据文件 7 中,报告 块 48740 损坏。

 

或者 在RMAN中

对于整个数据库

Rman> backup validate check logical database ;

For specific datafile

Rman> backup validate check logical datafile <fileno> ;

Once done query

SQL>Select * from v$database_block_corruption ;

 **如果在第 2 步中 v$database_block_corruption 报告的块数量很多,接下来最好使用第 4 步而不是第 3 步。

 

第 3 步 - 检查块是否是某个对象的一部分 - 适用于损坏的块号小的情况

查询 dba_extents,确认坏块是否属于任何对象。

SQL> select segment_name, segment_type, owner
       from dba_extents
      where file_id = <Absolute file number>
        and <corrupted block number> between block_id
            and block_id + blocks -1;

如果块不属于任何对象,查询dba_free_space 确认坏块是否属于数据文件的可用空间。

SQL> Select * from dba_free_space where file_id= <Absolute file number>
     and <corrupted block number> between block_id and block_id + blocks -1;

第 4 步 - 查找受影响的块并验证其是否属于任何段的一种比较好的方法是使用 RMAN,这种方法既好用又便捷。

如果在第 2 步中已经运行了 rman 验证,请直接转到下面给出的 sqlplus 脚本,以确认对象。

rmantarget/nocatalogorrmantarget/nocatalogor rman target sys/ nocatalog

 

run {
allocate channel d1 type disk;
allocate channel d2 type disk;
------------------------------------------------------------------------
--  multiple channels may be allocated for parallelizing purposes
--  depends: RMAN - Min ( MAXOPENFILES , FILESPERSET ) 
--  Defaults: MAXOPENFILES =8, FILESPERSET =64 
------------------------------------------------------------------------
allocate channel dn type disk;
backup check logical validate database;

 

注意:如果RDBMS是小于11g并且处于非归档模式下,则数据库必须处于 mounted 模式

  

*** 在进行进一步操作之前,*必须*运行并完成 RMAN 命令“backup check logical validate database”。
*** 此命令完成(基于文件)后将会填充“v$database_block_corruption”视图。
*** 如果未完成,在接下来的步骤中您就有可能得到无效/不完整的信息。

 运行以下 sql 查询,以确定块是位于可用空间中还是已占用空间中

set lines 200 pages 10000
col segment_name format a30

SELECT e.owner, e.segment_type, e.segment_name, e.partition_name, c.file#
, greatest(e.block_id, c.block#) corr_start_block#
, least(e.block_id+e.blocks-1, c.block#+c.blocks-1) corr_end_block#
, least(e.block_id+e.blocks-1, c.block#+c.blocks-1)
- greatest(e.block_id, c.block#) + 1 blocks_corrupted
, null description
FROM dba_extents e, vdatabase_block_corruption c WHERE e.file_id = c.file# AND e.block_id <= c.block# + c.blocks - 1 AND e.block_id + e.blocks - 1 >= c.block# UNION SELECT s.owner, s.segment_type, s.segment_name, s.partition_name, c.file# , header_block corr_start_block# , header_block corr_end_block# , 1 blocks_corrupted , 'Segment Header' description FROM dba_segments s, vdatabase_block_corruption c WHERE e.file_id = c.file# AND e.block_id <= c.block# + c.blocks - 1 AND e.block_id + e.blocks - 1 >= c.block# UNION SELECT s.owner, s.segment_type, s.segment_name, s.partition_name, c.file# , header_block corr_start_block# , header_block corr_end_block# , 1 blocks_corrupted , 'Segment Header' description FROM dba_segments s, vdatabase_block_corruption c
WHERE s.header_file = c.file#
AND s.header_block between c.block# and c.block# + c.blocks - 1
UNION
SELECT null owner, null segment_type, null segment_name, null partition_name, c.file#
, greatest(f.block_id, c.block#) corr_start_block#
, least(f.block_id+f.blocks-1, c.block#+c.blocks-1) corr_end_block#
, least(f.block_id+f.blocks-1, c.block#+c.blocks-1)
- greatest(f.block_id, c.block#) + 1 blocks_corrupted
, 'Free Block' description
FROM dba_free_space f, v$database_block_corruption c
WHERE f.file_id = c.file#
AND f.block_id <= c.block# + c.blocks - 1
AND f.block_id + f.blocks - 1 >= c.block#
ORDER BY file#, corr_start_block#;

第 5 步 - 以非 SYS 或 SYSTEM(用户)的用户身份创建一个虚拟表

SQL> connect scott/password

在包含出现坏块的数据文件的表空间中创建虚拟表,并使用 nologging 选项,以防止生成 redo记录:

SQL> create table s (
       n number,
       c varchar2(4000)
     ) nologging tablespace <tablespace name having the corrupt block> ; 

不同的存储参数可以被用来适应特定的环境。

我们使用 PCTFREE 99以加快该块的格式化

确认表是被创建在正确的表空间中,通过查询 user_segments:

SQL> select segment_name,tablespace_name from user_segments
      where segment_name='S' ;

 
请注意,在11gR2中,由于延迟段创建概念,从上面提到的 user_segments 查询可能不会报告。在这种情况下,查询 USER_TABLES 

SQL> select segment_name,tablespace_name from user_tables where segment_name='S' ;

第 6 步 - 在虚拟表上创建触发器,一旦重新使用坏块,该触发器便会引发异常

以 sysdba 身份连接,并创建以下触发器:

请注意,在出现文件号提示时,输入相关文件号(v$datafile 中的 rfile# 值)

CREATE OR REPLACE TRIGGER corrupt_trigger 
  AFTER INSERT ON scott.s 
  REFERENCING OLD AS p_old NEW AS new_p 
  FOR EACH ROW 
DECLARE 
  corrupt EXCEPTION; 
BEGIN 
  IF (dbms_rowid.rowid_block_number(:new_p.rowid)=&blocknumber)
 and (dbms_rowid.rowid_relative_fno(:new_p.rowid)=&filenumber) THEN 
     RAISE corrupt; 
  END IF; 
EXCEPTION 
  WHEN corrupt THEN 
     RAISE_APPLICATION_ERROR(-20000, 'Corrupt block has been formatted'); 
END; 
/

出现块编号提示时,输入坏块的块编号。
出现文件号提示时,输入损坏的数据文件的相关文件号(v$datafile 中的 rfile# 值)。

第 7 步 - 为受影响的数据文件中的表分配空间。

请注意:
1)如果这是一个ASSM表空间,你可能需要重复此步骤数次。也就是说,创建多个表和分配多个 extent。
并周期性地查看 dba_extents,以确保空闲空间现在分配给一个虚拟表。
这是因为ASSM将自动确定下一个 extent 的大小

2)建议确保数据文件 AUTOEXTEND 置为 OFF,以防止其增长。

 

请注意:如果database 版本是 10.2.0.4/11.1.0.7,dummy table 创建在 ASSM 表空间,那么手动分配extent时,可能遇到下面的bug。
请确保在手动分配extent前安装patch 6647480

Bug 6647480 - Corruption / OERI [kddummy_blkchk] .. [18021] with ASSM (Doc ID 6647480.8)

首先通过查询 dba_free_space 查找 extent 大小  

SQL> Select BYTES from dba_free_space where file_id=<file no> and <corrupt block no> between block_id and block_id + blocks -1;

BYTES
---------------- ---------- ---------- ---------- ---------- ------------
 65536

在本例中,它的大小是 64K。因此,按照以下方法分配 extent:

SQL> alter table scott.s
allocate extent (DATAFILE 'E:\xxxx\test.ORA' SIZE 64K);

 

如果在这个数据文件中有多个64K的空闲 extent,则可能需要使用这个循环:

BEGIN
for i in 1..1000000 loop
EXECUTE IMMEDIATE 'alter table scott.s allocate extent (DATAFILE '||'''E:\xxxx\test.ORA''' ||'SIZE 64K) ';
end loop;
end ;
/

继续分配空间直到坏块成为 scott.s 的一部分 — 使用以下查询进行检查:

SQL> select segment_name, segment_type, owner
       from dba_extents 
      where file_id = <Absolute file number>
        and <corrupt block number> between block_id 
            and block_id + blocks -1 ;

 

 

第 8 步 - 向虚拟表中插入数据以格式化块

示例代码(取决于表空间的大小,循环的次数可能发生变化):

BEGIN 
FOR i IN 1..1000000000 LOOP 
INSERT /*+ APPEND */ INTO scott.s select i, lpad('REFORMAT',3092, 'R') from dual; 
commit ; 
END LOOP; 
END;

 或者

BEGIN
  FOR i IN 1..1000000000 LOOP
    INSERT INTO scott.s VALUES(i,'x');
  END LOOP;
END;
/

 或使用以下包含 2 个循环的代码:

Begin
  FOR i IN 1..1000000000 loop
    for j IN 1..1000 loop
      Insert into scott.s VALUES(i,'x');
    end loop;
    commit;
  END LOOP;
END; 

 

每向表中插入一行就会触发触发器,且一旦向坏块中插入第一行数据,就会产成 ORA-20000 异常。

第 9 步 - 通过运行 DBV 和 Rman 备份确定数据文件中的坏块情况

 运行 dbverify 或 RMAN 在损坏的数据文件(或整个数据库)上再次验证。它不会显示块损坏。

 确保你做两次手动日志切换或检查点,使得在内存中的信息写入到磁盘。

 RMAN 备份不会报告此块上的任何错误。

 

运行真实的备份操作之前,你可以在数据文件上重新运行 RMAN validate 命令,并检查 v$database_block_corruption 不再显示块被标记为损坏。

 对于数据库版本 <=10gR2

 Rman> Backup validate check logical datafile <fileno>,<fileno> ;

 对于数据库版本>=11gR1 

 Rman> Backup validate check logical datafile <fileno> ;

 

 Rman> validate datafile <fileno> block <blockno reported corrupt>, <blockno reported corrupt>  ;

 一旦完成

 SQL> SELECT * FROM V $ DATABASE_BLOCK_CORRUPTION;

 
第 10 步 - 删除第 4 步中创建的虚拟表

 

SQL> DROP TABLE scott.s ;

如果版本为 10gr1 及以上,同时使用purge选项以清空回收站

第 11 步 – 执行手动日志切换和检查点

执行两次日志切换和检查点,以便将在内存中格式化的块写入到磁盘并使 dbverify 不再报告错误

SQL>Alter system switch logfile ;  --> Do this couple of time

SQL>Alter system checkpoint ;

 

第 12 步 - 删除第 6 步中创建的触发器

SQL> DROP triggercorrupt_trigger ;

 

重要通知:

 Bug 7381632 - ORA-1578 Free corrupt blocks may not be reformatted when Flashback is enabled

 

参考

NOTE:1088018.1 - Master Note for Handling Oracle Database Corruption Issues



About Me


.............................................................................................................................................

● 本文来自于MOS

● 本文在itpub(http://blog.itpub.net/26736162/abstract/1/)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新

● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/

● 本文博客园地址:http://www.cnblogs.com/lhrbest

● 本文pdf版、个人简介及小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/

● 数据库笔试面试题库及解答:http://blog.itpub.net/26736162/viewspace-2134706/

● DBA宝典今日头条号地址:http://www.toutiao.com/c/user/6401772890/#mid=1564638659405826

.............................................................................................................................................

● QQ群号:230161599(满)、618766405

● 微信群:可加我微信,我拉大家进群,非诚勿扰

● 联系我请加QQ好友(646634621),注明添加缘由

● 于 2017-08-01 09:00 ~ 2017-08-31 22:00 在魔都完成

● 文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解

● 版权所有,欢迎分享本文,转载请保留出处

.............................................................................................................................................

● 小麦苗的微店:https://weidian.com/s/793741433?wfr=c&ifr=shopdetail

● 小麦苗出版的数据库类丛书:http://blog.itpub.net/26736162/viewspace-2142121/

.............................................................................................................................................

使用微信客户端扫描下面的二维码来关注小麦苗的微信公众号(xiaomaimiaolhr)及QQ群(DBA宝典),学习最实用的数据库技术。

   小麦苗的微信公众号      小麦苗的DBA宝典QQ群1     小麦苗的DBA宝典QQ群2        小麦苗的微店

.............................................................................................................................................

时间: 2024-08-19 05:16:02

如何格式化不属于任何段的损坏块 (文档 ID 1526163.1)的相关文章

快速修复损坏的Word文档的方法

Word文档时常会因为各种原因而损坏,这时候不用着急,我们可以利用Word自带的功能或者其他的软件来修复. 第一种方案:利用Word2002/2003的打开修复功能 利用Word2000/2003的打开并修复功能启动Word2003/2007,单击文件,打开,在Word2007中则是左上方的圆形图标.在打开对话框选中需要修复的Word文档,单击打开按钮旁边的下三角按钮,在弹出的下拉菜单中选中打开并修复选项,即可对损坏的文档进行修复,修复完成后,Word会自动显示文档内容. 第二种方案:使用Off

修复损坏的Word文档的几种实用方法

Word 文档是许多电脑用户写作时使用的文件格式,当您辛辛苦苦写完一篇Word文档后,发现它因损坏而无法打开时,一定非常着急.其实,您不必心焦,因为我们还是有一些方法可以修复损坏文档,恢复受损文档中的文字.下面是具体的步骤. 1 采用专用修复功能 ①在"文件"菜单上,单击"打开". ②在"查找范围"列表中,单击包含要打开的文件的驱动器.文件夹或Internet 位置. ③在文件夹列表中,定位并打开包含文件的文件夹. ④选择要恢复的文件. ⑤单击&

Word文档损坏修复的几种实用方法

Word 文档是许多电脑用户写作时使用的文件格式,当您辛辛苦苦写完一篇Word文档后,发现它因损坏而无法打开时,一定非常着急.其实,您不必心焦,因为我们还是有一些方法可以修复损坏文档,恢复受损文档中的文字.下面是具体的步骤. Word修复工具(修复出错遇到问题需要关闭) V1.0 中文绿色版 1 采用专用修复功能 ①在"文件"菜单上,单击"打开". ②在"查找范围"列表中,单击包含要打开的文件的驱动器.文件夹或Internet 位置. ③在文件夹

如何修复损坏的Word文档

Word文档时常会因为各种原因而损坏,这时候不用着急,我们可以利用Word自带的功能或者其他的软件来修复. Step1:利用Word2002/2003的打开修复功能 利用Word2000/2003的打开并修复功能启动Word2003/2007,单击文件,打开,在Word2007中则是左上方的圆形图标.在打开对话框选中需要修复的Word文档,单击打开按钮旁边的下三角按钮,在弹出的下拉菜单中选中打开并修复选项,即可对损坏的文档进行修复,修复完成后,Word会自动显示文档内容. Setp2:使用Wor

Word无法读取文档,文档可能损坏,怎么办?

又一次出现这个问题:word无法读取文档,文档可能损坏.估计是上次断电造成的.以下是解决办法可以试试: 上面提示打开并修复文件,我就想,应该可以修复,点击了"显示帮助(E)",我就知道怎么做了.它告诉我两种方法来恢复文件. 方法一:这种方法我感觉效果比起第二种来说比较好,主要是恢复的效果比较好. 试图打开已损坏的文档,则会收到此错误信息.通过使用"恢复文本"转换器(可能需要安装)或"打开并修复"功能可能会恢复损坏的文件或其内容."打开并

五法宝抢救损坏的word文档

 文档-word文档损坏怎么修复"> 遇到以上已损坏的文档,其实,您不用着急,由于咱们还是有一些办法能够修正损坏文档,恢复受损文档中的文字. 下面是详细的操作过程. 1 采用专用修复功能 ①在"文件"菜单上,单击"打开". ②在"查找范围"列表中,单击包含要打开的文件的驱动器.文件夹或Internet 位置. ③在文件夹列表中,定位并打开包含文件的文件夹. ④选择要恢复的文件. ⑤单击"打开"按钮旁边的箭头,然

使用CSS样式表格式化XML文档

 这篇文章适用于有一定CSS基础的朋友们.如果你还没有CSS基础,可以到中文w3schools进行学习.      1.XML中引入CSS样式.      在XML中引入CSS样式表有两种方法.一种是在XML文档中直接嵌入CSS样式:另一种则是外部引入(似乎在WEB中很多引入的方式都有这两种).在XML中直接嵌入CSS样式的方法如下:  1 <?xml version="1.0" encoding="utf-8"?> 2 <?xml-stylesh

如何将Word文档段首词语批量加粗

每到期末总要整理一些复习资料给学生背诵,用Word整理名词解释时碰到了一个难题:整理好的名词有数百条,需要把每段开头的名词设置成黑体字以突出显示(如图1),但是逐一设置实在太麻烦了.请董师傅帮忙想个可以快速设置的好办法. 文档段首词语批量加粗-word批量加粗"> 董师傅:发现你整理的名词解释有一个共同点,就是在需要加粗的名词后都有一个冒号.利用这一特点我们可以用Word2010中的文本转换表格功能轻松实现名词批量加粗设置. 小提示 TIPS 因为文本转换表格功能只能识别半角的符号,如果使

如何在word文档中给一段文字加上底色

  如何在word文档中给一段文字加上底色          一个常用的软件,就能让一段文字更富表现力,如何用word给一段文字加上底色,快来学习吧! 效果图: 步骤 1.输入一段文字 2.选定要加底色的文字 3.在"格式"中选择"边框和底纹" 4.在"底纹"中选择想要的颜色,然后按"确定"按钮 5.就完成了!