ORA-01578、ORA-01110:数据块被损坏,此时无法读取文件

文章介绍了当Oracle数据库遇到由于重启或操作导致的LOB字段损坏问题时,如何查询和恢复不在线数据文件,以及提供五种不同的表修复方案,包括可视化处理、查询ROWID、建立中间表、重新导入数据和直接重建表的方法,每种方案都有其优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

查看问题:

1.使用oracle用户登录linux服务器,并进入sql模式

 # sqlplus /nolog

2.超级管理员的权限操作数据库

# conn /as sysdba;

3.查询不在线的数据

select name, status from v$datafile order by file#;

4.恢复数据

 # recover datafile

5.再次查询文件数据 文件为脱机状态

# select status from v$datafile where file# = 6;

6.将文件挂上网

# alter database datafile 13 online;

7.确认文件状态

# select name, status from v$datafile order by file#;

8.文件已经上线,可能还会出现一些问题 BLOB字段损坏导致部分表无法使用

参考了很多优秀博主的文章 可是有些不适用,便自己整理了一下

原因分析:

1.重启数据库 导致oracle在操作blob字段有问题。

2.应用操作数据库事,产生了锁等待。

3.出现锁等待,可以通过后台日志查看,后台会有对应的抛出一个ORA-00600错误。

4.根据 ORA-00600 错误跟踪,发现是一个INSERT 语句插入导致(可能是坏块造成),在数据库重启时插入数据有问题。

 5.通过select count(*) from user.table;查询对应的表会抛出错误,说明此数据文件下的某个块存在问题;

表修复方案:

方案一 可视化处理坏块(亲测有效):

操作需要用超级管理员登录,下面用的是plsql 也可以用控制台

1.查询坏块对应的分段类型、所属、分段名称

SELECT SEGMENT_TYPE, OWNER, SEGMENT_NAME
  FROM DBA_EXTENTS
 WHERE FILE_ID = 6
   AND 1962511 BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS - 1;

-- FILE_ID 文件标识  1962511 坏块的标识 可通过报错获取

 2.查询坏块的对应表

select table_name, column_name
  from dba_lobs
 where segment_name = 'SYS_LOB0000086896C00002$$'
   and owner = 'HLT20230606';
-- segment_name 分段名称 上一条语句中获取  owner 所有者

 3.根据表及字段查看到数据缺失有损坏,删除损坏块即可,置空应该也可以

select * from HLT20230606.S_BS_UIVIEWEXT;
DELETE FROM HLT20230606.S_BS_UIVIEWEXT WHERE FID = 'AnwAAACllIjajtru'

 优势:可视化发现错误并可以直接通过语句清理

 劣势:需要sql能执行查询语句,否则看不到错误点在哪里

方案二(查询坏块的rowid进行处理):

1.通过表空间 object_id,file_ID,block#,row# 构造ROWID 1)通过FILE_ID,BLOCK 查询出 segment_name:

SELECT SEGMENT_TYPE, OWNER, SEGMENT_NAME FROM DBA_EXTENTS
 WHERE FILE_ID = 6 
 AND 1962511 BETWEEN BLOCK_ID AND BLOCK_ID+BLOCKS

 2.构造坏块的ROWID

SELECT DATA_OBJECT_ID FROM USER_OBJECTS WHERE OBJECT_NAME = 'SYS_LOB0000086896C00002$$';

不懂为啥查不出来

SELECT DBMS_ROWID.ROWID_CREATE(1, 54649, 39, 24961, 0) FROM DUAL;
-- 54649 上面查出来的

3.通过ROWID 查询对应的列数据,并处理 

 SELECT ROWID,XXX FROM TABLE_NAME

优势:直接定位到有问题的数据

劣势:不懂为啥查不到数据

方案三(建立中间表处理):

1.建临时表

create table corrupted_lob_data (corrupted_rowid rowid);

 2.设置凹入

set concat off

3.打开设置输出服务器

set serveroutput on

 4.执行存过

declare
  error_1555 exception;
  pragma exception_init(error_1555, -1555);
  num number;
begin
  for cursor_lob in (select rowid r, &&lob_column
                       from &table_owner. &table_with_lob) loop
    begin
      num := dbms_lob.instr(cursor_lob.FSQL, hextoraw('889911'));
    exception
      when error_1555 then
        insert into corrupted_lob_data values (cursor_lob.r);
        commit;
    end;
  end loop;
end;

 5.获取有问题数据

select * from corrupted_lob_data;
select * from table(坏块的表) where rowid='AAEtzZAAOAACBpiAAP' ;--(BLOB坏的字段会出现ERROR字样)

通过上面的sql执行获取到具体哪些数据有问题,并对这些数据进行处理。

优势:循坏遍历到各个问题数据并放入中间表,更快的定位问题数据

劣势:执行存过报错的话,没办法解决

方案四(重新导入可用数据):

 1.10231 内部事件,设置在全表扫描时跳过损坏的数据块.

alter system set events='10231 trace name context forever,level 10';   

2.导出对应的表信息 

exp HLT20230606/kshdksk file=t.dmp tables=S_BS_UIVIEWEXT
-- exp 用户名/密码@数据库 file=t.dmp tables=有问题的表

3.删除表

 drop table t;

4.导入备份表

imp HLT20230606/kshdksk@orcl file=t.dmp tables=S_BS_UIVIEWEXT
-- imp 用户名/密码@数据库 file=t.dmp tables=有问题表

优势:直接整个问题表进行导入导出,对于数据量大的表,这种方式比较快

劣势:直接跳过问题数据,无法直观的看到有问题的数据

方案五(通过数据库直接建备份表转换):

 1.查询坏块对应的分段类型、所属、分段名称

SELECT SEGMENT_TYPE, OWNER, SEGMENT_NAME
  FROM DBA_EXTENTS
 WHERE FILE_ID = 6
   AND 1962511 BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS - 1;

-- FILE_ID 文件标识  1962511 坏块的标识 可通过报错获取

 2.查询坏块的对应表

select table_name, column_name
  from dba_lobs
 where segment_name = 'SYS_LOB0000086896C00002$$'
   and owner = 'HLT20230606';
-- segment_name 分段名称 上一条语句中获取  owner 所有者

3.使用10231事件忽略坏块

alter session SET EVENTS '10231 trace name context forever,level 10';

4.使用CTAS方式重建表

create table S_BS_UIVIEWEXT_NEW as select * from S_BS_UIVIEWEXT;

 5.重命名表rename table

rename S_BS_UIVIEWEXT to S_BS_UIVIEWEXT_BAK;
rename  S_BS_UIVIEWEXT_NEW to  S_BS_UIVIEWEXT;

6.重建索引rebuild index

alter index PK_BS_UIVIEWEXT rebuild;

7.关闭忽略坏块

alter session SET EVENTS '10231 trace name context off';

优势:直接整个问题表进行重建,对于数据量大的表,这种方式比较快

劣势:直接跳过问题数据,无法直观的看到有问题的数据

对象方案修复:

对于对象 可以直接重建对象

alter index indexname rebuild

### 关于 Oracle 数据库错误 ORA-01110ORA-27072 的解决方案 #### 错误 ORA-01110 的原因与处理方法 ORA-01110Oracle 数据库的一个常见错误代码,表明在尝试打开数据库时发生问题。通常是因为无法访问或找到指定的数据文件所引起[^1]。 对于此类问题的一种典型场景发生在服务器意外断电的情况下,这可能导致数据库文件损坏或丢失连接路径。具体实例显示,在北京某公司的案例中,由于机房突然停电造成服务器重启后遇到此错误,并且该情况下的数据库并无可用备份[^2]。 针对这种情况可以采取以下措施来解决问题: ```sql alter system set "_allow_resetlogs_corruption"=true scope=spfile; shutdown immediate; startup; alter database open resetlogs; ``` 上述命令序列允许通过设置特殊参数绕过某些一致性检查从而强制开启数据库并重置日志,但这可能会带来数据风险因此需谨慎操作[^4]。 另外一种可能的原因是特定表空间中的某个数据文件出现问题,如 `/u02/oradata/HOEGH/test_tbs01.dbf` 文件不可达的情况被报告为 ORA-01110 错误的一部分[^3]。此时应确认磁盘挂载状态以及文件权限等问题是否正常。 #### 错误 ORA-27072 的分析与应对策略 虽然未直接提供有关 ORA-27072 的详细描述,但从经验来看这个错误往往涉及到 I/O 操作失败或者是读写设备上的文件遇到了困难。这类错误可能是由多种因素引起的,比如存储介质故障、网络共享资源不可用或是操作系统层面的权限配置不当等。 为了有效解决 ORA-27072 问题,建议执行以下几个方面的排查工作: - **硬件健康状况评估**:验证硬盘或其他持久化储存装置是否存在物理损伤; - **环境变量及配置审查**:确保所有必要的环境变量已正确定义并且指向正确的目录位置; - **安全性和访问控制列表 (ACL)** 设置审核:保证运行 Oracle 实例的服务账户拥有足够的权利去访问所需资源。 如果经过以上步骤仍然未能成功修复,则考虑联系专业的技术支持团队获取进一步的帮助和支持。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zbqice007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值