数据库文件与SCN(system change number)
oracle内部逻辑时钟,用来反应数据库中所有变化,在运行过程中不断更新,SCN种类包括:
1、系统当前SCN
(1)、查看当前最新SCN
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
944288
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
944341
(2)、SCN与自然时间的转换
SQL> select scn_to_timestamp(944441) from dual;
SCN_TO_TIMESTAMP(944441)
--------------------------------------------------------------------23-AUG-11 09.05.57.000000000 AM
SQL> select timestamp_to_scn(to_date('2011-08-23 09:05.57','yyyy-mm-dd hh24:mi:ss')) from dual;
TIMESTAMP_TO_SCN(TO_DATE('2011-08-2309:05.57','YYYY-MM-DDHH24:MI:SS'))
--------------------------------------------------------------------
944442
2、checkpoint SCN(只会随检查点的发生而被更新)
(1)、STOP SCN(保存在控制文件中,有成END SCN)
实例正常运行时STOP SCN为空,当实例正常关闭时,oracle会在控制文件中记录下每个数据文件对应的STOP SCN号,用来在启动时检查控制文件中所有数据文件对应的STOP SCN号是否存在且一致,是则表示上次实例正常关闭,所有数据库文件对应的都已同步到磁盘,故无需进行redo/undo实例恢复;否则若发现控制文件中某个数据库文件对应的STOP SCN号为空,则表明上次实例非正常关闭,此次启动需要进行实例恢复,因此STOP SCN号用来判断下次启动时是否需要进行实例恢复。
SQL> select name,last_change# from v$datafile;
(从控制文件中读取STOP SCN,数据库运行时值为空,除非该数据文件未online)
NAME LAST_CHANGE#
-------------------------------------------------- ------------
/u01/app/oracle/oradata/ora10/system01.dbf
/u01/app/oracle/oradata/ora10/undotbs01.dbf
/u01/app/oracle/oradata/ora10/sysaux01.dbf
/u01/app/oracle/oradata/ora10/users01.dbf
/u01/app/oracle/oradata/ora10/example01.dbf
/u01/app/oracle/oradata/ora10/test01.dbf 919360
/u01/app/oracle/oradata/ora10/test02.dbf
SQL> select name,last_change# from v$datafile;
(在mount状态下)
NAME LAST_CHANGE#
-------------------------------------------------- ------------
/u01/app/oracle/oradata/ora10/system01.dbf 946441
/u01/app/oracle/oradata/ora10/undotbs01.dbf 946441
/u01/app/oracle/oradata/ora10/sysaux01.dbf 946441
/u01/app/oracle/oradata/ora10/users01.dbf 946441
/u01/app/oracle/oradata/ora10/example01.dbf 946441
/u01/app/oracle/oradata/ora10/test01.dbf 946441
/u01/app/oracle/oradata/ora10/test02.dbf 946441
SQL> oradebug setmypid;
SQL> oradebug dump controlf 4;
$ vim /u01/app/oracle/admin/ora10/udump/ora10_ora_30676.trc
***************************************************************************
DATA FILE RECORDS
***************************************************************************
(size = 428, compat size = 428, section max = 30, section in-use = 8,
last-recid= 11, old-recno = 0, last-recno = 0)
(extent = 1, blkno = 7, numrecs = 30)
DATA FILE #1:
(name #8) /u01/app/oracle/oradata/ora10/system01.dbf
creation size=0 block size=8192 status=0xe head=8 tail=8 dup=1
tablespace 0, index=1 krfil=1 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:173 scn: 0x0000.000e7109 08/23/2011 09:57:07
Stop scn: 0x0000.000e7109 08/23/2011 09:57:07
Creation Checkpointed at scn: 0x0000.00000009 06/30/2005 19:10:11
thread:0 rba: (0x0.0.0)
(2)、START SCN(保存在数据库文件中)
当checkpoint发生或实例关闭时,所有缓存数据都需要全部同步到所有数据文件中,则此时所有数据文件的start scn一致。数据库在启动实例时通过判断个各数据文件的start scn是否一致,来决定数据库是否需要进行介质恢复,若某个数据文件的start scn不是一致的且比其他数据文件的start scn旧,则需要对该数据文件进行redo,将其更新到最新的start scn号,才能打开实例。
因正常关闭实例时,所有数据文件中的start scn都会一致且是最新的,故关闭时写入到控制文件中的每个数据文件对应的stop scn就取每个数据文件中的start scn值为值。实例启动时若每个数据文件中保存的start scn都一致的,则表示所有数据文件都是正常的,无需进行介质恢复,而若控制文件中保存的每个数据文件对应的stop scn都和start scn一致,则表示上次实例正常关闭,也无需进行实例恢复(oracle在启动过程中首先检测是否需要介质恢复,然后检查是否需要实例恢复)
SQL> select name,checkpoint_change# from v$datafile_header;
(从数据文件头部查询的最新start scn)
NAME CHECKPOINT_CHANGE#
-------------------------------------------------- /u01/app/oracle/oradata/ora10/system01.dbf 946441
/u01/app/oracle/oradata/ora10/undotbs01.dbf 946441
/u01/app/oracle/oradata/ora10/sysaux01.dbf 946441
/u01/app/oracle/oradata/ora10/users01.dbf 946441
/u01/app/oracle/oradata/ora10/example01.dbf 946441
/u01/app/oracle/oradata/ora10/test01.dbf 946441
/u01/app/oracle/oradata/ora10/test02.dbf 946441
SQL> alter session set events 'immediate trace name file_hdrs level 10';
(导出文件查看start scn)
$ vim ora10_ora_3809.trc
*** SERVICE NAME:(SYS$USERS) 2011-08-25 07:22:20.538
*** SESSION ID:(159.3) 2011-08-25 07:22:20.538
DUMP OF DATA FILES: 8 files in database
DATA FILE #1:
(name #8) /u01/app/oracle/oradata/ora10/system01.dbf
creation size=0 block size=8192 status=0xe head=8 tail=8 dup=1
tablespace 0, index=1 krfil=1 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:174 scn: 0x0000.000e710a 08/25/2011 07:21:26
Stop scn: 0xffff.ffffffff 08/23/2011 09:57:07
Creation Checkpointed at scn: 0x0000.00000009 06/30/2005 19:10:11
thread:0 rba: (0x0.0.0)
enabled threads: 00000000 00000000 00000000 00000000 00000000 00000000
……....
Tablespace #0 - SYSTEM rel_fn:1
Creation at scn: 0x0000.00000009 06/30/2005 19:10:11
Backup taken at scn: 0x0000.00000000 01/01/1988 00:00:00 thread:0
reset logs count:0x2d2edfb8 scn: 0x0000.0006ce7b reset logs terminal rcv data:0x0 scn: 0x0000.00000000
prev reset logs count:0x2184ef74 scn: 0x0000.00000001 prev reset logs terminal rcv data:0x0 scn: 0x0000.00000000
recovered at 08/23/2011 07:57:52
status:0x2004 root dba:0x00400179 chkpt cnt: 174 ctl cnt:173
begin-hot-backup file size: 0
Checkpointed at scn: 0x0000.000e710a 08/25/2011 07:21:26
thread:1 rba: (0x33.3052.10)
enabled threads: 01000000 00000000 00000000 00000000 00000000 00000000
(3)、datafile checkpoint scn(保存在控制文件中)
只判断各个数据文件中的start scn是否一致作为实例启动时是否需要进程行介质恢复的依据并不严谨,因为实例启动时可能存在特殊情况:其所有数据文件的start scn一致,但均非最新scn而是旧的scn,这种情况下虽然所有start scn都一致,但实例是启动不了的,是需要对所有数据文件进行介质恢复的,因此启动时除了要判断start scn是否一致外,还应该核对start scn是否最新。为了对start scn是否最新进行界定,因此还需在控制文件中记录每个数据文件的datafile checkpoint scn,在更新数据文件的SCN时,会先更新控制文件中的datafile checkpoint scn,因此控制文件中的datafile checkpoint scn总是最新的,数据文件中的start scn只需与控制文件中的datafile checkpoint scn对比就知道是否是最新的了。
SQL> select name,checkpoint_change# from v$datafile;
(查看当前最新的datafile checkpoint scn)
NAME CHECKPOINT_CHANGE#
------------------------------------------- ------------------
/u01/app/oracle/oradata/ora10/system01.dbf 946442
/u01/app/oracle/oradata/ora10/undotbs01.dbf 946442
/u01/app/oracle/oradata/ora10/sysaux01.dbf 946442
/u01/app/oracle/oradata/ora10/users01.dbf 946442
/u01/app/oracle/oradata/ora10/example01.dbf 946442
/u01/app/oracle/oradata/ora10/test01.dbf 946442
/u01/app/oracle/oradata/ora10/test02.dbf 946442
SQL> oradebug setmypid;
SQL> oradebug dump controlf 4;
(导出控制文件,查看datafile checkpoint scn)
$ vim ora10_ora_4529.trc
***************************************************************************
DATA FILE RECORDS
***************************************************************************
(size = 428, compat size = 428, section max = 30, section in-use = 8,
last-recid= 11, old-recno = 0, last-recno = 0)
(extent = 1, blkno = 7, numrecs = 30)
DATA FILE #1:
(name #8) /u01/app/oracle/oradata/ora10/system01.dbf
creation size=0 block size=8192 status=0xe head=8 tail=8 dup=1
tablespace 0, index=1 krfil=1 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:174 scn: 0x0000.000e710a 08/25/2011 07:21:26
Stop scn: 0xffff.ffffffff 08/23/2011 09:57:07
Creation Checkpointed at scn: 0x0000.00000009 06/30/2005 19:10:11
thread:0 rba:(0x0.0.0)
(4)system checkpoint scn(保存在控制文件)
控制文件本身也在不断更新,如何知道控制文件的更新情况?system checkpoint scn就可以用来和各个数据文件的stasrt scn进行对比,如果system checkpoint scn比某个数据文件的start scn要旧,则说明控制文件不是最新的,启动时需要redo重做控制文件,因此启动时不仅如上所述要确认所有数据文件的start scn都要是最新的且一致,而且要需要保证system checkpoint scn与start scn一致才无需进行介质恢复。
SQL> select name,checkpoint_change# from v$database;
NAME CHECKPOINT_CHANGE#
--------- ------------------
ORA10 946442
SQL> oradebug setmypid;
SQL> oradebug dump controlf 4;
$ vim ora10_ora_4667.trc
(导出控制文件查看system checkpoint scn)
***************************************************************************
DATABASE ENTRY
***************************************************************************
(size = 316, compat size = 316, section max = 1, section in-use = 1,
last-recid= 0, old-recno = 0, last-recno = 0)
(extent = 1, blkno = 1, numrecs = 1)
08/21/2011 06:28:08
DB Name "ORA10"
Database flags = 0x00404001 0x00001000
Controlfile Creation Timestamp 08/21/2011 06:28:08
Incmplt recovery scn: 0x0000.00000000
Resetlogs scn: 0x0000.0006ce7b Resetlogs Timestamp 08/01/2011 16:30:48
Prior resetlogs scn: 0x0000.00000001 Prior resetlogs Timestamp 06/30/2005 19:09:40
Redo Version: compatible=0xa200100
#Data files = 7, #Online files = 7
Database checkpoint: Thread=1 scn: 0x0000.000e710a
Threads: #Enabled=1, #Open=1, Head=1, Tail=1
(5)各checkpoint SCN关系
*系统正常运行情况下:
System ckpt scn=datafile ckpt scn=start scn
Stop scn is null
*系统正常关闭情况下:
System ckpt scn=datafile ckpt scn=start scn 无需介质恢复
Stop scn is not null=start scn 无需实例恢复