数据库文件与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       无需实例恢复