Oracle 任何在OPEN RESETLOGS 之前检查在不完全恢复(时间点恢复)后数据库是否一致

如果自己搞不定可以找诗檀软件专业ORACLE数据库修复团队成员帮您恢复!

诗檀软件专业数据库修复团队

服务热线 : 13764045638 QQ号:47079569 邮箱:[email protected]

 

 

适用于:

Oracle Database – Enterprise Edition – 版本9.0.1.0 及以上
本文信息适用于任何平台。

目标

至少需要进行多少恢复量才能使从备份中还原的数据库被打开?

在执行RESTORE / RECOVER后,我们需要执行快速验证以确保数据库一致并准备好OPEN RESETLOGS

这种主动检查有助于防止在OPEN RESETLOGS期间或之后出现的几个问题。

本文通篇假设你正在从有效的备份中进行还原。

可能有这里没有讨论到的情况。如有疑问请咨询Oracle Support

解决方案

对于冷/脱机备份,无需归档日志/恢复。你只要使用resetlogs打开数据库。

但对于热/联机备份,必须应用从备份开始到结束的所有归档日志才能打开数据库这是恢复最低需要的数量。


要确定在备份完成时哪些日志是当前的,记下数据库备份的完成时间从备份日志中获取。

如果这个是一个RMAN 备份,你也可以查询RMAN 元数据。确保在调用rman之前设置环境变量 NLS_DATE_FORMAT ,使得时间戳和日期同时返回:

对于unix    

% export NLS_DATE_FORMAT=’dd-mon-rr hh24:mi:ss’
% rman target /

对于windows

> set nls_date_format=dd-mon-rr:hh24:mi:ss
> rman target /


要找到你的备份:

RMAN> LIST BACKUP OF DATABASE COMPLETED AFTER ‘<date>’;

RMAN> LIST BACKUP OF DATABASE COMPLETED AFTER ‘sysdate -n’;

设置 <date> 以限制你需要的备份的输出对于多片备份,记下最后创建的备份片backuppiece的完成时间。


本文通篇,在运行SQL 查询时,你应该在会话级别设置NLS_DATE_FORMAT如下:

SQL> alter session set nls_date_format=’DD-MON-YYYY HH24:MI:SS’ ;

检查 1: 检查点和模糊度

目的: 验证数据文件恢复到预定时间点(PIT),且它们是一致的(FUZZY = NO

通过从物理数据文件直接读取数据文件头,查询数据文件的当前状态和PIT(即数据库被恢复到的时间点) :

SQL> select fuzzy, status, error, recover, checkpoint_change#, checkpoint_time, count(*) from v$datafile_header group by fuzzy, status, error, recover, checkpoint_change#, checkpoint_time ;

FUZ STATUS  ERROR           REC CHECKPOINT_CHANGE# CHECKPOINT_TIME        COUNT(*)
— ——- ————— — —————— ——————– ———-
NO  ONLINE                                 5311260 31-AUG-2011 23:10:14          6
YES ONLINE                                 5311260 31-AUG-2011 23:10:14          1

a) 验证checkpoint_time / checkpoint_change#符合你预期的UNTIL TIME/ SCN。如果不是,如果有更多可用的归档日志,则进一步恢复数据库。

b) 如果一些数据文件的FUZZY = YES,这表示需要更多的恢复。如果这些归档日志丢失,识别此类数据文件并确定我们是否能够脱机他们。警告:如果它们被脱机,我们会丢失这些数据文件中的数据!

如果数据文件属于SYSTEMUNDO表空间,我们绝不能在没有适当的分析下脱机这样的数据文件。请咨询Oracle Support以进一步操作。

SQL> select file#, substr(name, 1, 50), substr(tablespace_name, 1, 15), undo_opt_current_change# from v$datafile_header where fuzzy=’YES’ ;

FILE# SUBSTR(NAME,1,50)                                  SUBSTR(TABLESPA UNDO_OPT_CURRENT_CHANGE#
———- ————————————————– ————— ————————
3 /u01/app/oracle/oradata/prod111/undotbs01.dbf      UNDOTBS1                         5117431


有时候,如果表空间名称不表示它是UNDO表,当我们在列UNDO_OPT_CURRENT_CHANGE#中看到非零值,则表示该数据文件包含undo段。

要使数据文件脱机:

SQL> alter database datafile <file#> offline ;


可以认为检查1通过,当:

a) 验证所有数据文件都在同一checkpoint_time,这也是你预期的时间点。

b) SYSTEM,UNDO 和所有需要的数据文件Fuzzy=NO。对于Fuzzy=YES的数据文件,进一步恢复或在无更多可用归档日志时使其脱机。

检查 2: 数据文件状态

目的: 验证status=RECOVER 的数据文件未被意外脱机

SQL> select status, enabled, count(*) from v$datafile group by status, enabled ;

STATUS  ENABLED      COUNT(*)
——- ———- ———-
SYSTEM  DISABLED            1
ONLINE  READ WRITE          4
RECOVER DISABLED            2

如果文件在RECOVER 状态,验证它们是否脱机:

SQL> select file#, substr(name, 1, 50), status, error, recover from v$datafile_header ;

如果你想要这些文件的数据能可访问,则使它们联机:

SQL> alter database datafile <file#> ONLINE ;

可以认为检查 2 通过,当:

所有想要的数据文件未脱机。 

检查 3: 绝对模糊Absolute Fuzzy

目的: 额外模糊检查 (绝对模糊检查) 

有时可能看到所有想要的数据文件Fuzzy=NO和有相同checkpoint_change#,但OPEN RESETLOGS仍失败

例如:

SQL> select fuzzy, status, error, recover, checkpoint_change#, checkpoint_time, count(*) from v$datafile_header group by fuzzy, status, error, recover, checkpoint_change#, checkpoint_time ;

FUZ STATUS  ERROR           REC CHECKPOINT_CHANGE#      CHECKPOINT_TIME   COUNT(*)
— ——- ————— — —————— ——————– ———-
NO  ONLINE                                 5311260 31-AUG-2011 23:10:14          7

SQL> ALTER DATABASE OPEN RESETLOGS ;

ORA-01194: file 4 needs more recovery to be consistent
ORA-01110: data file 3: ‘/u01/app/oracle/oradata/prod111/undotbs02.dbf’

因此,我们应执行额外模糊检查,称为绝对模糊检查Absolute Fuzzy Check

SQL> select hxfil file#, substr(hxfnm, 1, 50) name, fhscn checkpoint_change#, fhafs Absolute_Fuzzy_SCN, max(fhafs) over () Min_PIT_SCN from x$kcvfh where fhafs!=0 ;

FILE#      NAME                                               CHECKPOINT_CHANG ABSOLUTE_FUZZY_S     MIN_PIT_SCN
———- ————————————————– —————- —————- —————-
4 /u01/app/oracle/oradata/prod111/undotbs01.dbf               5311260          5311524          5311524
6 /u01/app/oracle/oradata/prod111/system01.dbf                5311260          5311379          5311524

注:即使对于我们应用了ANALYTICAL “MAX() OVER ()”函数的多行,列Min_PIT_SCN 会返回相同值。

以上查询表示恢复执行必须至少UNTIL SCN 5311524 使得数据文件一致并准备好打开。由于checkpoint_change# 小于Min_PIT_SCN,数据文件会请求更多恢复。

可以确认检查 3 通过,当:

a) 从以上查询未select任何行(即Min_PIT_SCN 对于所有数据文件为0 (Zero)

b) Min_PIT_SCN 被返回小于Checkpoint_Change#

检查 4: 所需的归档日志


查询控制文件以找出恢复所需的最近归档日志。假设备份在31-AUG-2011 23:20:14完成:

SQL> — V$ARCHIVED_LOG
SQL> —
SQL> ALTER SESSION SET NLS_DATE_FORMAT=’DD-MON-RR HH24:MI:SS’;
SQL> SELECT THREAD#, SEQUENCE#, FIRST_TIME, NEXT_TIME FROM V$ARCHIVED_LOG
WHERE ’31-AUG-11 23:20:14′ BETWEEN FIRST_TIME AND NEXT_TIME;

如果上面的查询不返回任何行,这可能是因为信息已经陈旧控制文件v$log_history运行以下查询。

SQL> — V$LOG_HISTORY  view does not have a column NEXT_TIME
SQL> —
SQL> ALTER SESSION SET NLS_DATE_FORMAT=’DD-MON-RR HH24:MI:SS’;
SQL> select a.THREAD#, a.SEQUENCE#, a.FIRST_TIME
from V$LOG_HISTORY a
where FIRST_TIME =
( SELECT MAX(b.FIRST_TIME)
FROM V$LOG_HISTORY b
WHERE b.FIRST_TIME < to_date(’31-AUG-11 23:20:14′, ‘DD-MON-RR HH24:MI:SS’)
) ;
SQL>

以上查询返回的sequence# 是在备份结束时的日志序列比如530 thread 1

对于最少恢复使用:(Sequence# as returned +1 )

RMAN> RUN
{
SET UNTIL SEQUENCE 531 THREAD 1;
RECOVER DATABASE;
}

如果这是使用这种SQLRAC实现,无需查询控制文件:

SQL> SELECT THREAD#, SEQUENCE#, FIRST_CHANGE#, NEXT_CHANGE# FROM V$ARCHIVED_LOG WHERE ’31-AUG-11 23:20:14′ BETWEEN FIRST_TIME AND NEXT_TIME;


对于最少恢复,使用日志序列和以上查询返回的最低NEXT_CHANGE#

可以认为检查4通过,当:

从备份开始到结束的所有归档日志可用于恢复中


检查5: OPEN RESETLOGS 后活动

OPEN RESETLOGS时,监控alert.log获得其他错误/信息。你可能在字典检查时看到一些信息如下:

Dictionary check beginning
Tablespace ‘TEMP’ #3 found in data dictionary, <(============================== (1)
but not in the controlfile. Adding to controlfile.
Tablespace ‘USERS’ #4 found in data dictionary,
but not in the controlfile. Adding to controlfile.
File #4 found in data dictionary but not in controlfile.
Creating OFFLINE file ‘MISSING00004’ in the controlfile. <(==================== (2)
File #5 is online, but is part of an offline tablespace. <(==================== (3)
data file 5: ‘/u01/app/oracle/oradata/prod111/example01.dbf’
File #7 found in data dictionary but not in controlfile. <(==================== (2)
Creating OFFLINE file ‘MISSING00007’ in the controlfile.
File #8 is offline, but is part of an online tablespace. <(==================== (4)
data file 8: ‘/u01/app/oracle/oradata/prod111/mydata02.dbf’
File #9 is online, but is part of an offline tablespace. <(==================== (3)
data file 9: ‘/u01/app/oracle/oradata/prod111/example02.dbf’
Dictionary check complete


我们讨论了以下几点:


(1) 
检查临时文件是否存在。如果不存在,按需添加:

SQL> select file#, name from v$tempfile ;

no rows selected

SQL> select file#, name from dba_temp_files ;

no rows selected

SQL> select tablespace_name, status, contents from dba_tablespaces where contents=’TEMPORARY’ ;

TABLESPACE_NAME                STATUS    CONTENTS
—————————— ——— ———
TEMP                           ONLINE    TEMPORARY

SQL> alter tablespace temp add tempfile ‘/u01/app/oracle/oradata/temp01.dbf’ size 10m ;

Tablespace altered.

SQL> select file#, substr(name, 1, 50), status, enabled from v$tempfile

FILE#    SUBSTR(NAME,1,50)                                  STATUS  ENABLED
——– ————————————————– ——- ———-
1 /u01/app/oracle/oradata/temp01.dbf                 ONLINE  READ WRITE

(2) , verify if the missing files really exist with original name. You may need to consult your pear DBAs, or refer alert.log / RMAN backup log or any such information which may provide clue about the actual file name. 看上去使用了“ALTER TABLESPACE USERS OFFLINE”命令脱机表空间。所以,验证丢失文件是否确实以原始名称存在。你可能需要咨询你的DBA同事,或者参考alert.log/ RMAN备份日志或者可能提供有关实际文件名的线索的任何信息。

如果你找到了文件,尝试重命名它们。如果没有,我们可以脱机数据文件或drop相关的表空间:

SQL> select file#, status, enabled, substr(name, 1, 50) from v$datafile where name like ‘%MISSING%’ ;

FILE#    STATUS  ENABLED    SUBSTR(NAME,1,50)
——– ——- ———- ————————————————–
4 OFFLINE DISABLED   /u01/app/oracle/product/11.1.0/db_1/dbs/MISSING000
7 OFFLINE DISABLED   /u01/app/oracle/product/11.1.0/db_1/dbs/MISSING000

SQL> alter database datafile 4 online ;
alter database datafile 4 online
*
ERROR at line 1:
ORA-01157: cannot identify/lock data file 4 – see DBWR trace file
ORA-01111: name for data file 4 is unknown – rename to correct file
ORA-01110: data file 4: ‘/u01/app/oracle/product/11.1.0/db_1/dbs/MISSING00004’

SQL> alter database rename file ‘MISSING00004’ to ‘/u01/app/oracle/oradata/prod111/users01.dbf’ ;

Database altered.

SQL> alter database rename file ‘MISSING00007’ to ‘/u01/app/oracle/oradata/prod111/users02.dbf’ ;

Database altered.

SQL> select tablespace_name, status from dba_tablespaces where tablespace_name in (select tablespace_name from dba_data_files where file_id in (4, 7)) ;

TABLESPACE_NAME                STATUS
—————————— ———
USERS                          OFFLINE

SQL> ALTER TABLESPACE USERS ONLINE ;

Tablespace altered.

在继续操作前,我们查询alert.log中这些文件的状态:

SQL> select a.file#, substr(a.name, 1, 50) file_name, a.status file_status, a.error, substr(a.tablespace_name, 1, 10) tablespace_name, b.status tablespace_status from v$datafile_header a, dba_tablespaces b
where a.tablespace_name=b.tablespace_name /* and a.file# in (4, 5, 7, 8, 9) */ ;

FILE# FILE_NAME                                     FILE_STATUS ERROR           TABLESPA TABLESPACE_STATUS
—– ——————————————— ———– ————— ——– ——————
1 /u01/app/oracle/oradata/prod111/system01.dbf  ONLINE                      SYSTEM   ONLINE
2 /u01/app/oracle/oradata/prod111/sysaux01.dbf  ONLINE                      SYSAUX   ONLINE
3 /u01/app/oracle/oradata/prod111/undotbs01.dbf ONLINE                      UNDOTBS1 ONLINE
4 /u01/app/oracle/oradata/prod111/users01.dbf   OFFLINE     OFFLINE NORMAL  USERS    OFFLINE <(== related to (2) in alert.log excerpt above
5 /u01/app/oracle/oradata/prod111/example01.dbf ONLINE                      EXAMPLE  OFFLINE <(== related to (3) in alert.log excerpt above
6 /u01/app/oracle/oradata/prod111/mydata01.dbf  ONLINE                      MYDATA   ONLINE
7 /u01/app/oracle/oradata/prod111/users02.dbf   OFFLINE     OFFLINE NORMAL  USERS    OFFLINE <(== related to (2) in alert.log excerpt above
8 /u01/app/oracle/oradata/prod111/mydata02.dbf  OFFLINE     WRONG RESETLOGS MYDATA   ONLINE <(=== related to (4) in alert.log excerpt above
9 /u01/app/oracle/oradata/prod111/example02.dbf ONLINE                      EXAMPLE  OFFLINE <(== related to (3) in alert.log excerpt above

9 rows selected.


因此,我们可以根据文件/归档日志的可用性和其他可能的因素,尝试纠正显示在以上查询的“ERROR”

我们继续,

(3) 看起来表空间被不一致脱机(ALTER TABLESPACE EXAMPLE OFFLINE IMMEDIATE )。如果在那时生成的归档日志被应用了,文件可能重新联机:

SQL> alter tablespace example ONLINE ;

Tablespace altered.

(4) 此表空间MYDATA2个数据文件文件#6&8。看起来File8被脱机了(使用ALTER DATABASE DATAFILE8 OFFLINE),且在OPEN RESETLOGS之前OFFLINE。如果在那时生成的归档日志在恢复期间被应用或从那时起的所有的归档日志可用于恢复,该文件可能重新联机:

SQL> alter database datafile 8 online ;
alter database datafile 8 online
*
ERROR at line 1:
ORA-01190: control file or data file 8 is from before the last RESETLOGS
ORA-01110: data file 8: ‘/u01/app/oracle/oradata/prod111/mydata02.dbf’

SQL> alter tablespace mydata online ;
alter tablespace mydata online
*
ERROR at line 1:
ORA-01190: control file or data file 8 is from before the last RESETLOGS
ORA-01110: data file 8: ‘/u01/app/oracle/oradata/prod111/mydata02.dbf’

SQL> recover datafile 8 ;
Media recovery complete.
SQL> alter database datafile 8 online ;

Database altered.

SQL> alter tablespace mydata online ;

Tablespace altered.

请注意,不一定能成功恢复由于” ORA-01190: control file or data file x is from before the last RESETLOGS”错误失败的文件。

(5) 可能有这样的情况,在OPEN RESETLOGS之前表空间在只读模式。请参考下面的文章:

Note 266991.1 Recovering READONLY tablespace backups made before a RESETLOGS Open

参考

NOTE:266991.1 – Recovering READONLY tablespace backups made before a RESETLOGS Open
NOTE:238422.1 – RMAN recover database fails RMAN-6025 – v$archived_log.next_change# is 281474976710655


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *