如果介质故障影响到数据库的在线redo日志,那么适合的恢复过程依赖于以下考虑:
1)在线redo日志的配置:镜像或非镜像
2)介质故障的类型:临时的或永久的
3)介质故障影响的在线redo日志的类型:当前的,活动的,非归档的,或非活动的
下表显示在涉及在线redo日志的恢复情形中可能是至关重要的V$LOG状态信息。
状态 | 描述 |
---|---|
UNUSED | 在线redo日志从未被写过 |
CURRENT | 在线redo日志是活动的,即需要用于实例恢复,它是数据库当前正在写的日志。redo日志可以是打开或关闭的。 |
ACTIVE | 在线redo日志是活动的,需要用于实例恢复,但不是数据库当前正在写的日志。它可能用于块恢复和可能被归档或没有被归档。 |
CLEARING | 在ALTER DATABASE CLEAR LOGFILE语句之后日志正在被重建为一个空的日志。在日志被清除之后,状态更改为UNUSED。 |
CLEARING_CURRENT | 当前日志正在从关闭的线程中被清除。日志可能保持在这个状态如果在切换中存在某些故障比如I/O错误写新的日志头部。 |
INACTIVE | 日志不再需要用于实例恢复。它可能用于介质恢复,可能被归档或没有被归档。 |
1.在丢失多路复用在线redo日志组的一个成员之后恢复
可以在丢失多路复用在线redo日志组的一个成员之后恢复。在以下条件期间数据库继续如平常一样运行:
如果数据库的在线redo日志是多路复用的和如果每个在线redo日志组的至少一个成员不受介质故障影响,那么数据库继续像平常一样运行,但错误信息会被写到日志写跟踪文件和数据库的alert_SID.log。
你可以采取以下一个操作解决多路复用在线redo日志组缺失成员的问题:
1)如果硬件问题是临时的,那么纠正它。日志写进程如同问题从未存在一样访问先前不可用的在线redo日志文件。
2)如果硬件问题是永久的,那么删除损坏的成员和使用以下步骤增加一个新的成员。
注:新增加的成员不提供冗余直到日志组被重用。
a.在V$LOGFILE中定位损坏的成员的文件名称。如果文件是不可访问的,状态会是INVALID。
SELECT GROUP#, STATUS, MEMBER
FROM V$LOGFILE
WHERE STATUS=‘INVALID’;
GROUP# STATUS MEMBER
------- ----------- ---------------------
0002 INVALID /disk1/oradata/trgt/redo02.log
b.删除损坏的成员。例如,从组2中删除成员redo2.log,执行以下语句:
ALTER DATABASE DROP LOGFILE MEMBER ‘/disk1/oradata/trgt/redo02.log’;
c.增加新的成员到组。例如,增加redo2b.log到组2,执行以下语句:
ALTER DATABASE ADD LOGFILE MEMBER ‘/disk1/oradata/trgt/redo02b.log’ TO GROUP 2;
如果增加的文件已经存在,那么它必须如其它组成员一样的大小和你必须指定REUSE选项。
ALTER DATABASE ADD LOGFILE MEMBER ‘/disk1/oradata/trgt/redo02b.log’ REUSE TO GROUP 2
2.在丢失在线redo日志组的所有成员之后恢复
如果介质故障损坏在线redo日志组的所有成员,那么取决于受故障影响的在线redo日志组的类型和数据库的归档模式,不同的场景会发生。
如果损坏的在线redo日志组是当前的和活动的,那么需要崩溃恢复;否则就不需要。下表列出了各种恢复场景。
如果组是… | 那么… | 和你可以… |
---|---|---|
不活动的 | 它不需要用于崩溃恢复 | 清除归档或未归档组。 |
活动的 | 它需要用于崩溃恢复 | 尝试执行检查点和清除日志。如果不可能,那么你必须使用闪回数据库或还原备份和执行不完全恢复直到最近可用的redo日志。 |
当前的 | 这是数据库当前正在写的redo日志 | 尝试清除日志;如果不可能,那么你必须使用闪回数据库或还原备份和执行不完全恢复直到最近可用的redo日志。 |
确认损坏组是活动的或不活动的:
1)在V$LOGFILE中定位丢失的redo日志的文件名称和寻找它对应的组号。
SELECT GROUP#, STATUS, MEMBER FROM V$LOGFILE;
GROUP# STATUS MEMBER
------- --------- --------------------------
0001 /oracle/dbs/log1a.f
0001 /oracle/dbs/log1b.f
0002 INVALID /oracle/dbs/log2a.f
0002 INVALID /oracle/dbs/log2b.f
0003 /oracle/dbs/log3a.f
0003 /oracle/dbs/log3b.f
2)确认哪个组是活动的。
SELECT GROUP#, MEMBERS, STATUS, ARCHIVED
FROM V$LOG;
GROUP# MEMBERS STATUS ARCHIVED
------ ------- --------- -----------
0001 2 INACTIVE YES
0002 2 ACTIVE NO
0003 2 CURRENT NO
2.1.丢失非活动的在线redo日志组
如果状态是INACTIVE的在线redo日志组的所有成员是损坏的,那么过程取决于是否可以修复损坏非活动redo日志组的介质问题。如果故障是临时的,那么纠正问题。当需要时日志写进程可以重用redo日志组。如果故障是永久的,那么损坏的非活动在线redo日志组最终中止正常的数据库操作。执行ALTER DATABASE CLEAR LOGFILE语句手动重新初始化损坏组。
2.1.1.清除非活动的归档redo
当数据库打开或关闭时你可以清除非活动的redo日志组。这个过程取决于损坏的组是否已经归档。
清除非活动的已经归档的在线redo日志组:
1)如果数据库是关闭的,那么启动新实例和挂载数据库:
STARTUP MOUNT
2)重新初始化损坏的日志组。
ALTER DATABASE CLEAR LOGFILE GROUP 2;
2.1.2.清除非活动的未归档redo
清除还未归档的redo日志允许它被重用而不归档它。这个操作让备份不可用的如果它们在日志中的最后更改之前启动,除非在日志中的第一个更改之前文件被脱机。因此,如果你需要清除的日志文件用于恢复一个备份,那么你不能恢复那个备份。清除还没归档的redo日志会由于缺失日志阻止你从备份中完全恢复。
清除非活动的未归档的在线redo日志组:
1)如果数据库是关闭的,那么启动新实例和挂载数据库:
STARTUP MOUNT
2)使用UNARCHIVED关键字清除日志。
SQL> ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 2;
如果存在脱机的数据文件需要被清除的日志来将它联机,那么需要关键字UNRECOVERABLE DATAFILE。数据文件必须被删除因为必要的将数据文件联机的redo日志正在被清除和不存在它的副本。
SQL> ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 2 UNRECOVERABLE DATAFILE;
3)使用操作系统工具立即备份数据库中所有的数据文件,以便有一个备份可以用来完全恢复而不依赖于被清除的日志组。
% cp /disk1/oracle/dbs/*.dbf /disk2/backup
4)使用ALTER DATABASE语句备份数据库的控制文件。
SQL> ALTER DATABASE BACKUP CONTROLFILE TO ‘/oracle/dbs/cf_backup.f’;
2.1.3.CLEAR LOGFILE操作故障
ALTER DATABASE CLEAR LOGFILE语句可能由于介质故障失败报I/O错误当不能做以下操作:
1)通过在当前配置的redo日志文件名称下重建来迁移redo日志文件到备选的介质
2)重用当前配置的日志文件名称来重建redo日志因为文件本身是无效的或不可用的
在这些情况中,ALTER DATABASE CLEAR LOGFILE语句(在收到I/O错误之前)成功通知控制文件日志在被清除和不需要归档。I/O错误发生在CLEAR LOGFILE语句尝试创建新的redo日志文件和写零到它的步骤中。这个事实反映在V$LOG.CLEARING_CURRENT中。
2.2.丢失活动的在线redo日志组
如果数据库正在运行和丢失的活动redo日志不是当前的日志,那么执行ALTER SYSTEM CHECKPOINT语句。如果操作成功,那么活动的redo日志变为非活动的,可以遵循“丢失非活动在线redo日志组”中的步骤。如果操作是不成功的,或数据库已经中止,那么取决于归档模式,执行本章节中的其中一个步骤。
当前的日志是LGWR正在写的日志。如果LGWR I/O操作失败,那么LGWR终止和实例故障。在这种情况中,你必须还原备份,执行不完全恢复和使用RESETLOGS选项打开数据库。
2.2.1.在非归档模式中从活动的日志丢失中恢复
在这个场景中,数据库归档模式是NOARCHIVELOG。
从非归档模式中活动在线日志组丢失中恢复:
1)如果介质故障是临时的,那么纠正问题以便数据库在需要时可以重用组。如果介质故障不是临时的,那么使用以下步骤。
2)从一致的整个数据库备份(数据文件和控制文件)中还原数据库。
% cp /disk2/backup/*.dbf $ORACLE_HOME/oradata/trgt/
3)挂载数据库。
STARTUP MOUNT
4)由于在线redo日志不能备份,你不能使用数据文件和控制文件还原它们。为允许数据库重置在线redo日志,你必须首先模拟不完全恢复:
RECOVER DATABASE UNTIL CANCEL
CANCEL
5)使用RESETLOGS选项打开数据库
ALTER DATABASE OPEN RESETLOGS;
6)一致地关闭数据库。
SHUTDOWN IMMEDIATE
7)制作整个数据库备份。
2.2.2.在归档模式中从活动的日志丢失中恢复
在这个场景中,数据库归档模式是ARCHIVELOG。
从归档模式活动的在线redo日志组丢失中恢复:
1)开始不完全介质恢复,恢复直到损坏的日志之前的日志。
2)确保丢失的redo日志当前的名称可以被用来做新创建的文件。如果不可以,那么重命名损坏的在线redo日志组的成员到新的位置。
ALTER DATABASE RENAME FILE “/disk1/oradata/trgt/redo01.log” TO “/tmp/
redo01.log”;
ALTER DATABASE RENAME FILE “/disk1/oradata/trgt/redo02.log” TO “/tmp/
redo02.log”;
3)使用RESETLOGS选项打开数据库:
ALTER DATABASE OPEN RESETLOGS;
注:必须重新执行从不完全恢复的结束点到现在执行的所有更新。
2.3.丢失多个redo日志组
如果你已经丢失多个在线redo日志组,那么使用最困难的日志恢复方法来恢复。困难的顺序,从最困难到最不困难,如下:
1)当前在线redo日志
2)活动在线redo日志
3)未归档的在线redo日志
4)不活动的在线redo日志
来源:《Oracle Database Backup and Recovery User’s Guide,19c》