28-ORA-01110数据文件读取错误

文章目录

  • [ORA-01110: error in data file n](#ORA-01110: error in data file n)
    • 一、报错现象(原文)
    • 二、原因分析
    • [三、场景一:文件找不到(ORA-01157 + ORA-01110)](#三、场景一:文件找不到(ORA-01157 + ORA-01110))
      • [3.1 判断文件是真丢还是假丢](#3.1 判断文件是真丢还是假丢)
      • [3.2 有备份:标准恢复](#3.2 有备份:标准恢复)
      • [3.3 无备份且数据可弃:offline drop 保全库](#3.3 无备份且数据可弃:offline drop 保全库)
      • [3.4 路径变了:rename datafile](#3.4 路径变了:rename datafile)
    • [四、场景二:块损坏(ORA-01578 + ORA-01110)](#四、场景二:块损坏(ORA-01578 + ORA-01110))
      • [4.1 定位坏块归属](#4.1 定位坏块归属)
      • [4.2 DBV 全文件校验,确认损坏范围](#4.2 DBV 全文件校验,确认损坏范围)
      • [4.3 修复](#4.3 修复)
    • [五、vdatafile 状态速查表](#五、vdatafile 状态速查表)
    • 六、验证
    • 七、预防

ORA-01110: error in data file n

一、报错现象(原文)

ORA-01110 自己的内容很简单:

复制代码
ORA-01110: data file 5: '/u01/app/oracle/oradata/orcl/users01.dbf'

只有文件号和路径,没有别的信息。这是因为它几乎从不单独出现------ORA-01110 的作用是给前面的主错误补充"哪个文件出的事"这行线索。常见三种组合:

复制代码
-- 组合一:文件找不到(启动时)
ORA-01157: cannot identify/lock data file 5 - see DBWR trace file
ORA-01110: data file 5: '/u01/app/oracle/oradata/orcl/users01.dbf'

-- 组合二:文件校验失败(启动时)
ORA-01122: database file 5 failed verification check
ORA-01110: data file 5: '/u01/app/oracle/oradata/orcl/users01.dbf'

-- 组合三:块损坏(运行期,查某张表时)
ORA-01578: ORACLE data block corrupted (file # 5, block # 128)
ORA-01110: data file 5: '/u01/app/oracle/oradata/orcl/users01.dbf'

处理思路也由此而来:ORA-01110 负责指路,真正的原因和修法看伴随错误,分三条线走。

二、原因分析

复制代码
ORA-01110(哪个文件)
   │
   ├──► 伴随 ORA-01157:文件不在/读不了 ──► 被删、路径变、权限
   │
   ├──► 伴随 ORA-01122:文件头对不上 ──► 旧备份文件、SCN 不一致(见 26/27 篇)
   │
   └──► 伴随 ORA-01578:块级损坏 ──► 存储坏块、异常断电

三、场景一:文件找不到(ORA-01157 + ORA-01110)

3.1 判断文件是真丢还是假丢

复制代码
$ ls -l /u01/app/oracle/oradata/orcl/users01.dbf
ls: cannot access ...: No such file or directory   -- 真没了

$ ls -l ...
-rw-r--r-- 1 root root ... users01.dbf             -- 在,但属主是 root:权限问题

Windows 环境先看回收站,误删的文件经常还能直接还原。同时查库内登记:

sql 复制代码
SQL> startup mount
SQL> select file#, name, status from v$datafile where file# = 5;

3.2 有备份:标准恢复

复制代码
RMAN> startup mount
RMAN> restore datafile 5;
RMAN> recover datafile 5;
RMAN> alter database open;

3.3 无备份且数据可弃:offline drop 保全库

先把库开起来,不让一个文件拖死整库:

sql 复制代码
SQL> startup mount
SQL> alter database datafile 5 offline drop;

Database altered.

SQL> alter database open;

offline drop 不是删文件,是把该文件标记为脱离,让 open 跳过它------文件上的数据等于放弃了。之后清掉旧登记、重建表空间:

sql 复制代码
-- 能导的数据先导(exp/expdp 该表空间下还能读的对象)
SQL> drop tablespace users including contents and datafiles;
SQL> create tablespace users
  2  datafile '/u01/app/oracle/oradata/orcl/users01.dbf' size 500m;

限制:system / sysaux 表空间的文件不能走这条路,只能 restore 恢复。

3.4 路径变了:rename datafile

文件还在,只是挪了位置(换盘、迁移存储),两种改法:

方法一,库能到 mount(适用于 system 表空间等任何文件):

sql 复制代码
SQL> startup mount
-- 操作系统层先移动文件:
-- mv /u01/old/users01.dbf /u02/new/users01.dbf
SQL> alter database rename file '/u01/old/users01.dbf'
  2  to '/u02/new/users01.dbf';
SQL> alter database open;

方法二,非 system 表空间且库是开的:

sql 复制代码
SQL> alter tablespace users offline;
-- 操作系统层移动文件
SQL> alter tablespace users rename datafile '/u01/old/users01.dbf'
  2  to '/u02/new/users01.dbf';
SQL> alter tablespace users online;

两步都别忘了"先在操作系统层把文件放到新路径",rename 只改控制文件里的登记,不搬文件。

四、场景二:块损坏(ORA-01578 + ORA-01110)

4.1 定位坏块归属

alert log 里的报错直接给了坐标:

复制代码
ORA-01578: ORACLE data block corrupted (file # 5, block # 128)
ORA-01110: data file 5: '...'

查这个块属于哪个对象:

sql 复制代码
select owner, segment_name, segment_type
from dba_extents
where file_id = 5
  and 128 between block_id and block_id + blocks - 1;

OWNER  SEGMENT_NAME     SEGMENT_TYPE
------ ---------------- -------------
SCOTT  BIG_ORDER        TABLE

4.2 DBV 全文件校验,确认损坏范围

复制代码
$ dbv file=/u01/app/oracle/oradata/orcl/users01.dbf blocksize=8192

DBVERIFY: Release 11.2.0.4.0 - Production on Mon Sep 28 10:00:00 2026

Total Pages Examined         : 64000
Total Pages Processed (Data) : 51234
Total Pages Marked Corrupt   : 2

重点看 Total Pages Marked Corrupt,它可能比 alert 里报的多------把范围一次摸清,别修一个又冒一个。Windows 下路径换写法即可:

复制代码
C:\> dbv file=D:\app\oracle\oradata\orcl\users01.dbf blocksize=8192

RMAN 也可以做校验,结果落在视图里:

复制代码
RMAN> backup validate check logical datafile 5;
sql 复制代码
SQL> select * from v$database_block_corruption;

4.3 修复

有备份,块级恢复,不用整文件 restore:

复制代码
-- 11g 及以前
RMAN> blockrecover datafile 5 block 128;

-- 12c 及以后写法
RMAN> recover corruption list;

无备份,以抢救数据为主。按 rowid 范围分批导出好块,绕开坏块,然后重建表:

sql 复制代码
select dbms_rowid.rowid_create(1, data_object_id, 5, 128, 0) min_rid,
       dbms_rowid.rowid_create(1, data_object_id, 5, 129, 0) max_rid
from dba_objects
where owner = 'SCOTT' and object_name = 'BIG_ORDER';
-- 用得到的 rowid 范围做 create table t as select ... where rowid between ...
-- 多段范围拼接,跳过损坏块

应急跳过坏块(全表扫描不再报错,但坏块数据不完整):

sql 复制代码
SQL> alter session set events '10231 trace name context forever, level 10';

这是应急手段,导完数据就关,不是让库带病长期运行的姿势。

五、v$datafile 状态速查表

排查时随手一条:

sql 复制代码
select file#, name, status from v$datafile;
status 含义 处理方向
SYSTEM system 表空间文件,在线 正常
ONLINE 在线,正常 正常
OFFLINE 被手工脱机 确认后 online,或继续恢复
RECOVER 需要介质恢复 recover datafile(见 27 篇)
SYSOFF 系统表空间文件处于脱机(异常状态) 恢复流程

配合 v$datafile_header 交叉验证(文件头层面的视角):

sql 复制代码
select file#, status, fuzzy, checkpoint_change# from v$datafile_header;

六、验证

sql 复制代码
-- 文件层面:状态全部正常
SQL> select file#, status from v$datafile;

-- 恢复层面:没有待恢复文件
SQL> select * from v$recover_file;
no rows selected

-- 块层面:DBV 复跑一遍,Marked Corrupt 为 0
-- $ dbv file=... blocksize=8192

最后业务侧抽查:坏块所属表 count 一下、关键行读一遍,能读就是修干净了。

七、预防

  • 数据文件的唯一保险是备份:RMAN 定期全备 + 归档,并确保 restore/recover/blockrecover 都演练过
  • 块损坏多源于存储层坏块和异常断电,RAID 健康巡检、UPS 比事后修复便宜得多
  • 迁移文件走 rename 流程(操作系统移动 + rename 登记),不要手工 mv 完就不管
  • 定期 backup validate 扫描数据文件,坏块在备份阶段发现,永远比在业务查询时报 ORA-01578 要体面
相关推荐
非优秀程序员1 小时前
第02章 杭电的英语老师与一台服务器|《互联网产品恩仇录》
数据库·node.js·代码规范
SelectDB6 小时前
SelectDB 是哪个公司的?是国产数据库吗?一篇讲清飞轮科技与 Apache Doris 的关系
数据库
这个DBA有点耶6 小时前
库内计算推理:一条SQL背后的算子融合,和外挂方案差了几次网络往返
数据库·人工智能·sql
这个DBA有点耶8 小时前
函数索引的“完全一致”有多苛刻:写法、字符集、类型,差一处就失效
数据库·mysql·代码规范
星恒随风8 小时前
MySQL 从零入门(三):表的约束详解
linux·服务器·数据库·笔记·mysql
Alluxio9 小时前
Alluxio + OCI:为 AI 工作负载实现亚毫秒访问延迟与可扩展吞吐
运维·数据库·人工智能·分布式·缓存·ai·语言模型
数据库急诊室_阿哲13 小时前
一次加索引建议的复核记录:从报告到签字
数据库·ai数据库
青瓦梦滋13 小时前
Redis主从复制
服务器·数据库·redis·缓存·bootstrap
慧都小妮子14 小时前
Wyn商业智能国产数据库适配:数据接入、分析缓存与审计日志验证清单
数据库·数据分析·数据可视化·审计日志·商业智能
Joy T15 小时前
Redis Lua 原子限流:Lua 脚本、竞态条件与并发控制
数据库·redis·lua·限流·竞态条件·redis scripting