Home  >  Article  >  Database  >  数据库open阶段关于检查点的校验

数据库open阶段关于检查点的校验

WBOY
WBOYOriginal
2016-06-07 16:36:391346browse

关于数据库open阶段时何时需要recovery: 1. oracle通过系统checkpoint scn,datafile checkpoint scn,start scn三者之间的比较来判断数据文件是否需要进行介质恢复. 2. 在redo 线程打开的情况下,即数据库open的情况下,stop scn会被设置为无穷大,当正常关

关于数据库open阶段时何时需要recovery:<br> 1. oracle通过系统checkpoint scn,datafile checkpoint scn,start scn三者之间的比较来判断数据文件是否需要进行介质恢复.<br> 2. 在redo 线程打开的情况下,即数据库open的情况下,stop scn会被设置为无穷大,当正常关闭时,stop scn等于datafile scn.<br> 这里需要注意的是,stop scn是存放在controlfile中的,网上部分资料说是存在datafile header中,这个说法是错误的 。<br> 3. oracle在open之前是先判断是否进行介质恢复,然后再是判断是否进行instance recovery。<br> 4. 关于4种scn的关系如下:<br> system checkpoint scn — 存放在controlfile中<br> datafile checkpoint scn –存放在controlfile中<br> start scn —存放在datafile header中<br> stop scn —存放在controlfile中

system scn,datafile checkpoint scn,start scn,这3种scn用于判断数据文件是否需要进行介质恢复。这3个相等这不需要介质恢复。
如何这4个都相等,那么就不需要进行实例恢复。stop scn是用于判断是否进行实例恢复的。

5. 如果stop scn比其他的几个scn要大,那么就需要进行instance recover,需要进行扫描redo,实例恢复的起点是low cache rba,终点
是redo log的最末端。

自己的理解:
关于上述几点小鱼测试过程中并不如此,oracle恢复是分介质恢复和实例恢复,介质恢复是需要利用备份集和归档来恢复的,而实例恢复则是自动的利用在线日志进行的。
但是试想一种情况,shutdown abort数据库,然后删除掉所有的在线日志,而此时你重启这个数据库到mount状态,可以清晰的看见如下过程:
SQL> select checkpoint_change#,name from v$datafile;

CHECKPOINT_CHANGE# NAME
------------------ --------------------------------------------------
1303384 G:\ORACLE\PRODUCT\10.2.0\ORADATA\UTF8\SYSTEM01.DBF
1303384 G:\ORACLE\PRODUCT\10.2.0\ORADATA\UTF8\UNDOTBS01.DB
F

1303384 G:\ORACLE\PRODUCT\10.2.0\ORADATA\UTF8\SYSAUX01.DBF
1303384 G:\ORACLE\PRODUCT\10.2.0\ORADATA\UTF8\USERS01.DBF

SQL> select name,checkpoint_change#,checkpoint_count from v$datafile_header;

NAME CHECKPOINT_CHANGE# CHECKPOINT_COUNT
---------------------------------------- ------------------ ----------------
G:\ORACLE\PRODUCT\10.2.0\ORADATA\UTF8\SY 1303384 112
STEM01.DBF

G:\ORACLE\PRODUCT\10.2.0\ORADATA\UTF8\UN 1303384 75
DOTBS01.DBF

G:\ORACLE\PRODUCT\10.2.0\ORADATA\UTF8\SY 1303384 112
SAUX01.DBF

G:\ORACLE\PRODUCT\10.2.0\ORADATA\UTF8\US 1303384 111
ERS01.DBF

SQL> select checkpoint_change# from v$database;

CHECKPOINT_CHANGE#
------------------
1303384

SQL> alter database open resetlogs;
alter database open resetlogs
*
ERROR at line 1:
ORA-01194: file 1 needs more recovery to be consistent
ORA-01110: data file 1: 'G:\ORACLE\PRODUCT\10.2.0\ORADATA\UTF8\SYSTEM01.DBF'

看出system的checkpoint scn、控制文件中记录的数据文件的checkpoint scn和数据文件头记录的start scn是一致,

但是由于这里删除了所有的redo,open resetlogs过程中会重置所有redo序号,然后重新生成redo,但是由于缺少之前的在线redo,导致实例恢复失败,也就提示需要进一步恢复file 1

那么来说:
这里小鱼想提出并不是所谓的实例恢复就不会报出所谓的错误的,数据库在open阶段能自动实现的就是实例恢复,介质恢复是需要dba去手动执行的,

但是如果实例恢复失败了,比如缺少在线redo,那么一样会出现无法打开数据库,并不意味着实例恢复好像不影响数据库的能否正常打开,这点需要特别明确。

这里小鱼看了好几个版本的数据库何时需要恢复,整理下想法:(eygle也曾经这么说过)
1 控制文件记录的checkpoint cnt也就是检查点计数和数据文件头记录的checkpoint cnt是否一致,并不是说数据文件头的启动scn和控制文件中记录的scn一致

控制文件记录的checkpoint cnt和数据文件头的checkpoint cnt这个可以用来区分数据文件和控制文件是否来自同一版本,而不是从备份中得来。

checkpoint scn检查点计数这个主要是用于区分数据文件和控制文件是否来自同一版本,这个非常重要。

有网友做过测试即使数据文件的启动scn和控制文件中记录的数据文件的checkpint scn不一致,同样可以打开数据库。(注意控制文件中也记录了数据文件的checkpoint scn)

2 数据文件头的启动scn和控制文件的结束scn是否一致,不一致则需要进行实例恢复,实例恢复是自动的,但是并不意味不重要,如果由于缺少日志恢复失败一样无法打开数据库。

puber上面的一个网友的测试说明:
SQL> startup mount
SQL> select file#,checkpoint_change#,last_change# from v$datafile;

FILE# CHECKPOINT_CHANGE# LAST_CHANGE#
---------- ------------------ ------------
1 2bc309 2bc309
2 2bc309 2bc309
3 2bc309 2bc309
4 2bc309 2bc309
5 2bc309 2bc309

SQL>
SQL> select checkpoint_change# from v$datafile_header;

CHECKPOINT_CHANGE#
------------------
2bc309
2bc309
2bc309
2bc309
2bc309

SQL>
SQL> select checkpoint_change# from v$database;

CHECKPOINT_CHANGE#
------------------
2bc309

SQL> host

RMAN> restore datafile 3
2> ;

........

RMAN> recover datafile 3;

........

RMAN> exit

恢复管理器完成。

Cocuments and SettingsRequieM>exit

SQL> select file#,checkpoint_change#,last_change# from v$datafile;

FILE# CHECKPOINT_CHANGE# LAST_CHANGE#
---------- ------------------ ------------
1 2bc309 2bc309
2 2bc309 2bc309
3 2bc309 2bc308
4 2bc309 2bc309
5 2bc309 2bc309

SQL>
SQL> select checkpoint_change# from v$datafile_header;

CHECKPOINT_CHANGE#
------------------
2bc309
2bc309
2bc308
2bc309
2bc309

SQL> alter database open;

在作上述步骤同时选取几个时间点,对控制文件和数据文件头作dump。过程太长,只贴一下结果。

1、shutdown以后;
2、restore以后;
3、recover以后;
4、open db以后。

结果如下:
时间点 控制文件 数据文件头
chk cnt chk scn chk cnt chk scn
1 302 2bc309 302 2bc309
2 302 2bc309 264 233c60 --看出这里restore时数据文件头的启动cnt和控制文件记录cnt不一致
3 303 2bc309 303 2bc308 --recover后利用归档和在线日志已经达到了cnt一致,但是checkpoint scn并不一致
4 304 2bc30a 304 2bc30a

结论:当恢复结束时,文件头内的chk scn比控制文件中的chk scn小1,但是chk cnt是完全相同的。

因此,数据库打开时比较的是检查点计数和数据文件头的启动scn和控制文件的数据文件的结束scn,而不是比较数据文件头启动scn和控制文件的checkpoint scn。

自己做了一个测试:
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>
SQL> startup mount;

rman>restore datafile 4;

alter session set events 'immediate trace name controlf level 12';

controlfile trace:
DUMP OF CONTROL FILES, Seq # 1497 = 0x5d9
V10 STYLE FILE HEADER:
Compatibility Vsn = 169870080=0xa200300
Db ID=4166494968=0xf857aaf8, Db Name='ORA10G'
Activation ID=0=0x0
Control Seq=1497=0x5d9, File size=432=0x1b0
File Number=0, Blksiz=16384, File Type=1 CONTROL
Logical block number 1 (header block)

DATA FILE #4:
(name #4) G:\ORACLE\PRODUCT\10.2.0\ORADATA\ORA10G\USERS01.DBF
creation size=0 block size=8192 status=0xe head=4 tail=4 dup=1
tablespace 4, index=4 krfil=4 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:316 scn: 0x0000.001818e7 05/28/2014 17:21:16 --这个checkpoint cnt 316就是控制文件记录的检查点计数,scn: 0x0000.001818e7是控制文件记录的数据文件的checkpoint scn
Stop scn: 0x0000.001818e7 05/28/2014 17:21:16 -- 这个Stop scn: 0x0000.001818e7就是所谓的数据文件的stop scn,注意的是这个stop scn并不是在数据文件中,而是记录在控制文件中
Creation Checkpointed at scn: 0x0000.00002997 08/26/2008 12:33:50
thread:0 rba:(0x0.0.0)

alter session set events 'immediate trace name file_hdrs level 10';

file_hdrs trace:
DATA FILE #4:
(name #4) G:\ORACLE\PRODUCT\10.2.0\ORADATA\ORA10G\USERS01.DBF
creation size=0 block size=8192 status=0xe head=4 tail=4 dup=1
tablespace 4, index=4 krfil=4 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:316 scn: 0x0000.001818e7 05/28/2014 17:21:16 这一段并不是数据文件头的信息,而只是控制文件中关于这个数据文件的信息,这个一定要特别注意,曾几何时这个困扰了小鱼好长时间
Stop scn: 0x0000.001818e7 05/28/2014 17:21:16
Creation Checkpointed at scn: 0x0000.00002997 08/26/2008 12:33:50
thread:0 rba:(0x0.0.0)

这段file header才是数据文件头的信息
V10 STYLE FILE HEADER:
Compatibility Vsn = 169870080=0xa200300
Db ID=4166494968=0xf857aaf8, Db Name='ORA10G'
Activation ID=0=0x0
Control Seq=1474=0x5c2, File size=12000=0x2ee0
File Number=4, Blksiz=8192, File Type=3 DATA
Tablespace #4 - USERS rel_fn:4
Creation at scn: 0x0000.00002997 08/26/2008 12:33:50
Backup taken at scn: 0x0000.00000000 01/01/1988 00:00:00 thread:0
reset logs count:0x3285b2bc scn: 0x0000.00093009 reset logs terminal rcv data:0x0 scn: 0x0000.00000000
prev reset logs count:0x2790538b scn: 0x0000.00000001 prev reset logs terminal rcv data:0x0 scn: 0x0000.00000000
recovered at 05/28/2014 17:25:05
status:0x0 root dba:0x00000000 chkpt cnt: 314 ctl cnt:313 --首先这个chkpt cnt: 314就是数据文件头的检查点计数checkpoint cnt
begin-hot-backup file size: 0
Checkpointed at scn: 0x0000.001817ee 05/28/2014 17:20:29 --而这个checkpointed at scn: 0x0000.001817ee就是数据文件头的scn,也就是我们所谓的数据文件头的启动scn

SQL> select checkpoint_change#,last_change# from v$datafile;

CHECKPOINT_CHANGE# LAST_CHANGE#
------------------ ------------
1579239 1579239
1579239 1579239
1579239 1579239
1579239 1579239

V$datafile中Last_change#就是控制文件记录的数据文件的stop scn,v$datafile的checkpoint_change#是控制文件中记录的数据文件的checkpoint scn

SQL> select checkpoint_change#,checkpoint_count from v$datafile_header;

CHECKPOINT_CHANGE# CHECKPOINT_COUNT
------------------ ----------------
1579239 318
1579239 108
1579239 318
1578990 314

V$datafile_header中的checkpoint_change#就是数据文件头的checkpoint scn(也叫做start scn),v$datafile_header中的checkpoint_count就是数据文件头的checkpoint count

而我们查询v$datafile和v$datafile_header视图发现查询结果确实和我们上面dump controlfile和datafile header结果一致

比如这里的v$datafile_header中的checkpoint_change#是1578990正好对应于dump datafile header trace文件中的Checkpointed at scn: 0x0000.001817ee,而v$datafile_headers的checkpoint_count 314也正好对应于chkpt cnt: 314

SQL> recover datafile 4

SQL> select checkpoint_change#,last_change# from v$datafile;

CHECKPOINT_CHANGE# LAST_CHANGE#
------------------ ------------
1579239 1579239
1579239 1579239
1579239 1579239
1579239 1579238

SQL> select checkpoint_change#,checkpoint_count from v$datafile_header;

CHECKPOINT_CHANGE# CHECKPOINT_COUNT
------------------ ----------------
1579239 318
1579239 108
1579239 318
1579238 317

controlfile trace:
DATA FILE #4:
(name #4) G:\ORACLE\PRODUCT\10.2.0\ORADATA\ORA10G\USERS01.DBF
creation size=0 block size=8192 status=0xe head=4 tail=4 dup=1
tablespace 4, index=4 krfil=4 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:317 scn: 0x0000.001818e7 05/28/2014 17:21:16 --这里控制文件中记录checkpoint cnt变为了317,之前控制文件中记录的是316,这个checkpoint scn没有变化
Stop scn: 0x0000.001818e6 05/28/2014 17:21:16 --Stop scn: 0x0000.001818e7变为了Stop scn: 0x0000.001818e6,这里stop scn减少了1
Creation Checkpointed at scn: 0x0000.00002997 08/26/2008 12:33:50
thread:0 rba:(0x0.0.0)

datafile header trace:
DATA FILE #4:
(name #4) G:\ORACLE\PRODUCT\10.2.0\ORADATA\ORA10G\USERS01.DBF
creation size=0 block size=8192 status=0xe head=4 tail=4 dup=1
tablespace 4, index=4 krfil=4 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:317 scn: 0x0000.001818e7 05/28/2014 17:21:16
Stop scn: 0x0000.001818e6 05/28/2014 17:21:16
Creation Checkpointed at scn: 0x0000.00002997 08/26/2008 12:33:50
thread:0 rba:(0x0.0.0)

aux_file is NOT DEFINED
V10 STYLE FILE HEADER:
Compatibility Vsn = 169870080=0xa200300
Db ID=4166494968=0xf857aaf8, Db Name='ORA10G'
Activation ID=0=0x0
Control Seq=1499=0x5db, File size=12000=0x2ee0
File Number=4, Blksiz=8192, File Type=3 DATA
Tablespace #4 - USERS rel_fn:4
Creation at scn: 0x0000.00002997 08/26/2008 12:33:50
Backup taken at scn: 0x0000.00000000 01/01/1988 00:00:00 thread:0
reset logs count:0x3285b2bc scn: 0x0000.00093009 reset logs terminal rcv data:0x0 scn: 0x0000.00000000
prev reset logs count:0x2790538b scn: 0x0000.00000001 prev reset logs terminal rcv data:0x0 scn: 0x0000.00000000
recovered at 05/28/2014 17:47:28
status:0x0 root dba:0x00000000 chkpt cnt: 317 ctl cnt:316 -- checkpoint cnt从314变为了317,此时datafile header中记录的checkpoint cnt已经和controlfile中记录的checkpoint cnt一致了
begin-hot-backup file size: 0
Checkpointed at scn: 0x0000.001818e6 05/28/2014 17:21:16 --datafile header的checkpoint scn(start scn)也变为了 0x0000.001818e6和控制文件中记录的stop scn也已经一致了

此时这个数据库已经完成了检测:controlfile中记录的checkpoint cnt和datafile header中记录的checkpoint cnt一致;controlfile中记录的stop scn和datafile header中记录的checkpoint scn(也叫start scn)一致。

但是正如这个过程还有很多需要注意的地方,比如这个controlfile中记录的scn是什么,和启动数据库有什么关系,对于recovery还是要等后面借助bbed对block、recovery有深刻的认知后才能慢慢解开面纱。

其实探索这些东西短期内可能并不会为我们带来什么收益,但是正如小鱼个人认为,如果想突破所谓的瓶颈(一般人都会遇见,至少小鱼现在算是遇见了),比如在某些方面比如优化、sql tuning、troubleshooting、recovery等方面的有深入学习的探索的毅力和行为,坚持下去可能瓶颈就慢慢突破了!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn