共计 8724 个字符,预计需要花费 22 分钟才能阅读完成。
普通数据文件指:非 system 表空间、undo_tablespace 表空间、临时表空间和只读表空间的数据文件。它们损坏导致用户数据不能访问,不会导致 db 自身异常、实例崩溃、数据库不恢复就无法启动的情况。
恢复这样的数据文件可以采用高可用策略,在数据库 OPEN 状态下进行
10.1 普通数据文件损坏的后果
普通数据文件损坏后,只是用户的业务数据不同程度上无法访问(查询与修改),报错
ORA-01578,执行命令的会话不会被中断,即使是数据文件头部损坏检查点发生时实例也不会崩溃
–1 实例启动时,若普通数据文件丢失、无法访问或头部损坏,startup 命令只能启动到 mount 状态。
–2 实例运行时,若普通数据文件头损坏,在发生了检查点之后,由于检查点无法再该数据文件头部完成,此数据文件的状态在控制文件中会被自动设置为 off, 实例不会崩溃,alert log 中有 ORA-01171 由于检查点失败导致文件下线的错误记录,访问该数据文件 ORA-00376 错误,实例不再试图访问该文件,此时实例也能重启成功。
–3 实例运行时,若普通数据文件非头部数据块损坏,将导致需要访问受损数据行的命令无法执行,数据文件不会自动下线。
场景 1:在启动时发现普通数据文件 test01.dbf 不存在,数据块只能启动到 mount 状态
SQL> startup;
Database mounted.
ORA-01157:cannot identify/lock data file 5 -see DBWR trace file
ORA-01110:data file 5 : /u01/app/Oracle/oradata/orcl/test01.dbf
场景 2:在启动时发现普通数据文件 test01.dbf 头部损坏,db 只能启动到 mount 状态
SQL> startup force
Database mounted.
ORA-01122: database file 5 tailed verification check
ORA-01110: data file 5 : /u01/app/oracle/oradata/orcl/test01.dbf
ORA-01210: data file header is media corrupt
若使用 alter database datafile 5 offline,使 test01 数据文件下线,db 还是可以打开的,打开后 test01 数据文件中的数据都无法访问
SQL> alter database datafile 5 offline;
SQL> alter database open;
–1 损坏的数据文件属于存放历史分区信息的表空间,在线业务不需要或者暂时不需要访问
–2 损坏的数据文件属于一个或几个特定应用的表空间,但是其它相对独立的应用所使用的其他表空间仍然健康,这样做可以使其他应用先提供服务,保证数据库的局部高可用性
场景 3:在运行时普通数据文件头损坏,那么在发送检查点时数据文件会被强制下线,在 alter log 中
ORA-01171: datafile 5 going offline due to error advancing checkpoint
ORA-01122: database file 5 failed verification check
ORA-01110: data file 5 : /u01/app/oracle/oradata/orcl/test01.dbf
ORA-01210: data file header is media corrupt
导致文件内所有业务数据无法访问,比如查询 test.t1
SQL> select * from test.t1;
ERROR at line 1:
ORA-00376: file 5 cannot be read at this time
ORA-01110: data file 5 : /u01/app/oracle/oradata/orcl/test01.dbf
若此时重启实例,db 也能打开,但 5 号数据文件依然处于 offline,需要手动恢复。
SQL> startup force;
SQL> select * from v$datafile where file#=5;
ERROR at line 1:
ORA-01135: file 5 accessed for DML/query is offline
ORA-01110: data file 5 : /u01/app/oracle/oradata/orcl/test01.dbf
场景 4:如果表空间区管理方式是 LOCAL,在运行时,数据文件都不区位图(biimap)管理块损坏
SQL> create table t2 (id number) tablespace test;
ORA-01658: unable to create INITIAL extent for segment in tablespace TEST
场景 5:实例运行时,表、索引等段头损坏,导致需要读取、修改段头的操作失败
SQL> insert into test.t1(id,name) vales (2,’xxx’);
ORA-01578: ORACLE data block corrupted (file # 5,block # 202)
SYS@ orcl >conn yhqt/***
Connected.
YHQT@ orcl >select * from yhqtest_1;
select * from yhqtest_1
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 10, block # 135)
ORA-01110: data file 10: ‘/u01/app/oracle/oradata/orcl/yhqt01.dbf’
场景 6:保存数据的数据块坏块 (file # 10, block # 143)
YHQT@ orcl >select * from yhqtest_2;
select * from yhqtest_2
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 10, block # 143)
ORA-01110: data file 10: ‘/u01/app/oracle/oradata/orcl/yhqt01.dbf’
– 更多详细数据块块损坏见 DSI 系列的物理块损坏和逻辑块损坏
10.2 备份
RMAN> backup as compressed backupset tablespace test;
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-00558: error encountered while parsing input commands
RMAN-01009: syntax error: found “test”: expecting one of: “double-quoted-string, identifier, single-quoted-string”
RMAN-01007: at line 1 column 43 file: standard input
RMAN> backup as compressed backupset tablespace yhqt;
Starting backup at 18-JUL-19
using channel ORA_DISK_1
channel ORA_DISK_1: starting compressed full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00010 name=/u01/app/oracle/oradata/orcl/yhqt01.dbf
channel ORA_DISK_1: starting piece 1 at 18-JUL-19
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03009: failure of backup command on ORA_DISK_1 channel at 07/18/2019 17:59:04
ORA-19566: exceeded limit of 0 corrupt blocks for file /u01/app/oracle/oradata/orcl/yhqt01.dbf
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS CORRUPTION_CHANGE# CORRUPTIO
———- ———- ———- —————— ———
10 135 1 0 FRACTURED
5 2199 1 9533291 CORRUPT
5 2207 1 9579846 CORRUPT
5 2231 1 9620379 CORRUPT
RMAN> run {
set maxcorrupt for datafile 10 to 135;
backup tablespace yhqt;
}2> 3> 4>
executing command: SET MAX CORRUPT
Starting backup at 18-JUL-19
using channel ORA_DISK_1
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00010 name=/u01/app/oracle/oradata/orcl/yhqt01.dbf
channel ORA_DISK_1: starting piece 1 at 18-JUL-19
channel ORA_DISK_1: finished piece 1 at 18-JUL-19
piece handle=/u01/app/oracle/fra/ORCL/backupset/2019_07_18/o1_mf_nnndf_TAG20190718T180019_gm0jsmbb_.bkp tag=TAG20190718T180019 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
Finished backup at 18-JUL-19
Starting Control File and SPFILE Autobackup at 18-JUL-19
piece handle=/u01/app/oracle/fra/ORCL/autobackup/2019_07_18/o1_mf_s_1013968820_gm0jsndn_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 18-JUL-19
备份 SYSAUX 表空间为镜像复制
RMAN> backup as copy tablespace sysaux;
Starting backup at 18-JUL-19
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile copy
input datafile file number=00002 name=/u01/app/oracle/oradata/orcl/sysaux01.dbf
output file name=/u01/app/oracle/fra/ORCL/datafile/o1_mf_sysaux_gm0jwl05_.dbf tag=TAG20190718T180153 RECID=2 STAMP=1013968917
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:07
Finished backup at 18-JUL-19
Starting Control File and SPFILE Autobackup at 18-JUL-19
piece handle=/u01/app/oracle/fra/ORCL/autobackup/2019_07_18/o1_mf_s_1013968921_gm0jws37_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 18-JUL-19
运行以上命令 RMAN 命令时,先确保数据库在 mount 状态或者 open 状态,open 状态下还需要开启归档日志模式。
10.3 恢复
普通数据文件的恢复的核心步骤:是该数据文件下线、从备份还原(restore 或 switch)使用增量备份或重做日志恢复(recover 命令),最后再令文件上线
普通数据文件恢复的主要特点是既可以在数据库 mount 状态下恢复(过程中 db 不可用),也可以保持 db 在 open 状态下恢复(db 局部可用)。数据文件头部损坏的情况可能需要特殊处理。
10.3.1 恢复前的准备
与关键数据文件的恢复一样,进入 mount 状态时恢复的前提,确保参数文件和控制文件正常。
若关键数据文件(system,undo)有损坏,首先应该恢复关键数据文件。
这一篇讨论的内容建立在参数文件、控制文件、关键数据文件正常的情况下。
若在 open 状态下对普通数据文件进行修复,首先必须确保被恢复的文件已处于 offline 状态。
10.3.2 非文件头部损坏后的恢复
只要文件头部没有损坏(包括文件丢失),文件就不会被自动下线,也不会出现 ORA-01210 错误,可以使用此节的步骤进行恢复,数据库处于 mount 状态为低可用恢复策略,数据库处于 open 状态为高可用恢复策略。
–1 使用 shutdown abort 关闭实例
–2 执行 startup mount 启动到 mount 状态
–3 RMAN 执行 restore(或 switch)还原损坏的普通数据文件
–4 通过 RMAN 执行 recover database 利用归档日志和在线重做日志恢复数据文件
–5 alter database open 打开数据库
以 yhqt01.dbf 数据文件为例
–mount 状态恢复
RMAN> run {
shutdown abort;
startup mount;
restore datafile ‘/u01/app/oracle/oradata/orcl/yhqt01.dbf’;
recover database;
alter database open;}
–open 状态恢复,实例未关闭
RMAN> run {
sql’alter database datafile 10 offline’;
restore datafile 10;
recover datafile 10;
sql’alter database datafile 10 online’;
}
–open 状态,实例已关闭
RMAN> run {
startup mount;
sql’alter database datafile 10 offline’;
alter database open;
restore datafile 10;
recover datafile 10;
sql’alter database datafile 10 online’;
}
10.3.3 文件头部损坏后的恢复
数据文件头部损坏之后,如果又处于 offline 状态,将来执行 restore 命令时通道会“不认识”这种文件,导致还原无法完成。Alert log 中出现 ORA-01210
场景:yhqt01.dbf 文件头部已经损坏,随后检查点也已发生,告警日志中出现 ORA-01210 和 ORA-01171 错误,并已在控制文件中将 yhqt01.dbf 文件的状态修改为 offline,
用户访问 yhqt 表空间的对象都返回 ORA-00376: file 10 cannot be read at this time
此时用 restore 命令还原 yhqt01.dbf 文件将意外引发 RMAN-06010 错误,原因是控制文件表示该文件已下线,restore 发现 yhqt01.dbf 存在,通道还是会访问 yhqt01.dbf 文件头部,
以确认其信息是否与控制文件中的一致,但损坏的是文件头,命令失败。
解决:
–1 删除头部已损坏的数据文件,这样通道就不会尝试检查文件头,当做文件丢失处理
–2 在 db 处于 mount 状态用 alter database datafile … online 将数据文件修改为 online,再使用 restore
RMAN> restore datafile 10;
ORA-01135: file 10 accessed for DM/query is offline
ORA-01110: datafile 10 :/u01/app/oracle/oradata/orcl/yhqt01.dbf
RMAN-06010: error while looking up datafile 10
删除该数据文件
$ rm /u01/app/oracle/oradata/orcl/yhqt01.dbf
RMAN> restore datafile 10;
RMAN> recover datafile 10;
SQL> alter database open;
SQL> alter database datafile 10 online;
所以数据文件头部损坏后的修复步骤应该在低可用策略与高可用策略的基础上,再根据相关数据文件是否已经 offline 区分,总共 3 种:
–1 未下线低可用策略恢复(online,mount)
–2 已下线低可用策略恢复(offline,mount)
–3 已下线高可用策略恢复(offline,open)
1 的恢复的主要步骤
–1 使用 shutdown abort 关闭实例
–2 执行 startup mount 启动实例到 mount 状态
–3 RMAN 执行 restore 或 switch 还原损坏的普通数据文件
–4 RMAN 执行 recover database 利用归档日志和在线日志恢复数据文件
–5 alter database open 打开数据库,恢复完成
RMAN> run {
shutdown abort;
startup mount;
restore datafile 10;
recover database;
alter database open;}
2 的恢复主要步骤
–1 使用 shutdown abort 关闭实例
–2 startup mount 到 mount 状态
–3 alter databse datafile 10 online 将数据文件在控制文件中的状态修改为上线
–4 RMAN> restore datafile 10; 还原数据文件
–5 RMAN> recover database;
–6 SQL>alter database open;
RMAN> run {
shutdown abort;
startup mount;
sql’alter database 10 online’;
restore datafile 10;
recover database;
alter database open;}
3 的恢复主要步骤
–1 使用操作命令删除损坏的头部的普通数据文件,若非头部损坏忽略此步骤
–2 如果实例已经停止,startup mount 启动到 mount 状态,如果数据库 open 状态,则忽略此步骤
–3 alter database 10 offline;
–4 如果符合第二步的条件,使用 alter database open 打开数据库,否则忽略此步骤
–5 使用 RMAN> restore datafile 10;
–6 RMAN>recover tablespace 或者 recover datafile,利用归档和 redo log 恢复数据文件
–7 执行 alter database datafile 10 online;
$ rm /u01/app/oracle/oradata/orcl/yhqt01.dbf
– 实例未关闭
RMAN> run {
sql’alter database datafile 10 offline’;
restore datafile 10;
recover datafile 10;
sql’alter database datafile 10 online’;
}
– 实例已关闭
RMAN> run {
startup mount;
sql’alter database datafile 10 offline’;
alter database open;
restore datafile 10;
recover datafile 10;
sql’alter database datafile 10 online’;
}
更多 Oracle 相关信息见 Oracle 专题页面 https://www.linuxidc.com/topicnews.aspx?tid=12
: