如何格式化不属于任何段的损坏块

[[196780]]

一、问题症状:

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。

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

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

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

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

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

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

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

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

  1. $ rman target / nocatalog 
  2. or 
  3. $ rman target sys/ nocatalog 
  4.  
  5.  
  6. run { 
  7. allocate channel d1 type disk; 
  8. allocate channel d2 type disk; 
  9. ---------------------------------------------------------------------- 
  10. --  multiple channels may be allocated for parallelizing purposes 
  11. --  depends: RMAN - Min ( MAXOPENFILES , FILESPERSET )  
  12. --  Defaults: MAXOPENFILES =8, FILESPERSET =64  
  13. ---------------------------------------------------------------------- 
  14. allocate channel dn type disk; 
  15. backup check logical validate database; 

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

*** 在进行进一步操作之前,*必须*运行并完成 RMAN 命令“backup check logical validate database”。

*** 此命令完成(基于文件)后将会填充“v$database_block_corruption”视图。

*** 如果未完成,在接下来的步骤中您就有可能得到无效/不完整的信息。

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

  1. SQL> connect scott/password 

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

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

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

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

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

  1. QL> select segment_name,tablespace_name from user_segments 
  2.       where segment_name='S' ;  

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

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

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

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

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

  1. CREATE OR REPLACE TRIGGER corrupt_trigger  
  2.   AFTER INSERT ON scott.s  
  3.   REFERENCING OLD AS p_old NEW AS new_p  
  4.   FOR EACH ROW  
  5. DECLARE  
  6.   corrupt EXCEPTION;  
  7. BEGIN  
  8.   IF (dbms_rowid.rowid_block_number(:new_p.rowid)=&blocknumber) 
  9.  and (dbms_rowid.rowid_relative_fno(:new_p.rowid)=&filenumber) THEN  
  10.      RAISE corrupt;  
  11.   END IF;  
  12. EXCEPTION  
  13.   WHEN corrupt THEN  
  14.      RAISE_APPLICATION_ERROR(-20000, 'Corrupt block has been formatted');  
  15. END;  
  16.  

出现块编号提示时,输入坏块的块编号。

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

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

请注意:

1)如果这是一个ASSM表空间,你可能需要重复此步骤数次。也就是说,创建多个表和分配多个 extent。

并周期性地查看 dba_extents,以确保空闲空间现在分配给一个虚拟表。

这是因为ASSM将自动确定下一个 extent 的大小

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

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

  1. SQL> Select BYTES from dba_free_space where file_id=<file noand <corrupt block nobetween block_id and block_id + blocks -1; 
  2.  
  3. BYTES 
  4. ---------------- ---------- ---------- ---------- ---------- ------------ 
  5.  65536  

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

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

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

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

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

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

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

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

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

或者

  1. BEGIN 
  2.   FOR i IN 1..1000000000 LOOP 
  3.     INSERT INTO scott.s VALUES(i,'x'); 
  4.   END LOOP; 
  5. END
  6.  

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

  1. Begin 
  2.   FOR i IN 1..1000000000 loop 
  3.     for j IN 1..1000 loop 
  4.       Insert into scott.s VALUES(i,'x'); 
  5.     end loop; 
  6.     commit
  7.   END LOOP; 
  8. END;   

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

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

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

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

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

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

对于数据库版本 <=10gR2

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

对于数据库版本>=11gR1

  1. Rman> Backup validate check logical datafile <fileno> ; 

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

一旦完成

  1. SQL> SELECT * FROM V $ DATABASE_BLOCK_CORRUPTION; 

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

  1. SQL> DROP TABLE scott.s ; 

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

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

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

  1. SQL>Alter system switch logfile ; --> Do this couple of time 
  2.  
  3. SQL>Alter system checkpoint ;  

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

  1. SQL> DROP triggercorrupt_trigger ;  

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/307045.html<

(0)
管理的头像管理
上一篇2025-05-26 22:50
下一篇 2025-05-26 22:52

相关推荐

  • jsp空间购买和交换数据空间怎么买,有哪些注意事项?

    购买JSP空间时,是否考虑过数据交换空间的性能?简米科技(2003年始创,23年行业沉淀)与酷番云(工信部一类增值电信全牌照)这类持牌自营机房的服务商,能确保数据交换的高效稳定,是值得优先选择的合作伙伴,为什么JSP空间需要搭配独立的数据交换空间从JSP应用特性看数据交换需求JSP基于Java技术,常用于企业级……

    2026-08-11
    0
  • 建网站用香港空间效果怎么样,香港空间稳定吗?

    建网站用香港空间,对于创建网站资产来说,核心价值在于免备案和全球带宽优势,尤其适合外贸、跨境电商和需要快速启动的项目,但你必须权衡国内访问延迟,并选择有资质的服务商以保证资产安全,香港空间的核心优势与适用边界免备案:节省时间就是节省成本国内服务器需要备案,通常需要10到20天,香港空间无需备案,域名解析后即可上……

    2026-08-11
    0
  • Java连接云数据库的方法是什么,如何操作

    Java连接云数据库的核心在于通过JDBC驱动,结合云服务商提供的连接地址、端口、数据库名及认证信息,配置安全策略(如SSL、IP白名单),即可实现稳定高效的远程数据库访问,基础准备:JDBC驱动与依赖管理连接云数据库前,需要确保开发环境具备对应的JDBC驱动,以最常见的MySQL为例,你需要引入mysql-c……

    2026-08-11
    0
  • 建网站公安联网备案必须使用数据码吗,备案流程是什么

    网站备案包括ICP备案和公安联网备案,两者缺一不可,公安联网备案必须使用服务商提供的数据码,选择持有合法资质的服务商是顺利通过备案的前提,为什么网站必须进行公安联网备案根据公安部《计算机信息网络国际联网安全保护管理办法》,网站开通后30日内必须到公安机关办理备案手续,未完成公安备案的网站,面临责令整改、关闭网站……

    2026-08-10
    0
  • 建一个企业网站大概需要多少钱?,怎么收费?

    建网站要多少钱,没有一个固定的数字,几百到几万都可能,但真正的“创建网站资产”绝不仅仅是初次投入的成本,而是基于长期稳定、合规和安全的持续性投入,其中核心取决于你选择了什么样的“地基”来承载你的业务,建站预算的构成与行业基准当你开始规划一个网站,最先面对的就是预算问题,一个常见的误区是只关注网站“看起来”的建造……

    2026-08-10
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注