SCN是当Oracle数据库更新后,由DBMS自动维护去累积递增的一个数字。当一笔交易commit时,LGWR会将log buffer写入redo log file,同时也会将该笔交易的SCN同步写入到redo log file内(wait-until-completed)。因此当你commit transaction时,在交易成功的讯息返回之前,LGWR必须先完整的完成上述行为之后,否则你是看不到提交成功的回应讯息。
可以查询目前系统最新的SCN
SQL>select dbms_flashback.get_system_change_number from dual;
可以理解,这里返回的SCN,也是目前redo log file最新的SCN纪录。因为commit后的交易才会有SCN,而一旦commit就会立刻写入redo log file中。
CHECKPOINT和SCN的关联
Checkpoint发生的目的就是要把存储在buffer内的已提交交易写回disk,否则一旦发生crash,需要进行recovery时,就必须花很多时间从redo log file内最后的SCN交易开始进行recovery,这样在商业应用上是很浪费时间和没有效率的。
当commit一笔交易时,只会立刻将redo buffer写入redo log file内,但是并不会马上将该update后的block(dirty block)同步写回disk datafile中,这是为了减少过多disk IO,所以采取batch方式写入。
When a checkpoint occurs. Oracle must update the headers of all datafiles to record the details of the checkpoint. This is done by the CKPT process. The CKPT process does not write blocks to disk; DBWn always performs that work.
在shutdown normal or shutdown immediate下,也就是所谓的clean shutdown, checkpoint也会自动触发。当发生checkpoint时,会把SCN写到四个地方去。三个地方在control file 内,一个在datafile header。
Control file三个地方为:
1、System checkpoint SCN
SQL> select to_char(checkpoint_change#, 'XXXXXXXXXXXX') from v$database;
TO_CHAR(CHECKPOINT_CHANGE#,'XX
-----------------------------------------------------------------
7161D7365DC
2、 Datafile checkpoint SCN
SQL> select name, to_char(checkpoint_change#,'XXXXXXXXXXXX') from v$datafile where name like '%gisdts01%';
NAME
-------------------------------------------------------------------
TO_CHAR(CHECKPOINT_CHANGE#,'XX
-------------------------------------------------------------------
/gisdata/datafile/gisdts01.dbf
7161D7365DC
3、Stop SCN
SQL> select name,last_change# from v$datafile where name like '%gisdts01%';
NAME
--------------------------------
/gisdata/datafile/gisdts01.dbf
正常datafile在read-write mode运作下,last_change#一定是null
还有一个SCN在datafile header内
4、Start SCN
SQL>select name,to_char(checkpoint_change#,'XXXXXXXXXXXX') from v$datafile_header where name like '%gisdts01%';
NAME
---------------------------------------------------------------
TO_CHAR(CHECKPOINT_CHANGE#,'XX
---------------------------------------------------------------
/gisdata/datafile/gisdts01.dbf
7161D7365DC
为什么储存在control file中要分为两个地方(system checkpoint scn, datafile checkpoint scn?)。当把一个tbs设为read-only时,他的scn会冻结停止,此时datafile checkpoint scn是不会再递增改变的,但是整体的system checkpoint scn却仍然会不断递增前进。所以这是为什么需要分别在两个地方储存SCN。
正常shutdown database后,SCN会发生什么变化?
可以把数据库开在mount mode
SQL> select to_char(checkpoint_change#,'XXXXXXXXXXXX') from v$database;
TO_CHAR(CHECKPOINT_CHANGE#,'XX
-------------------------------------------------------------
7161D7455B9
SQL>select name,to_char(checkpoint_change#,’XXXXXXXXXXXX’),to_char(last_change#
,’XXXXXXXXXXXX’) from v$datafile where name like '%gisdts01%';
NAME
-------------------------------------------------------------
TO_CHAR(CHECKPOINT_CHANGE#,'XX
-------------------------------------------------------------
TO_CHAR(LAST_CHANGE#,'XXXXXXXX
-------------------------------------------------------------
/gisdata/datafile/gisdts01.dbf
7161D7455B9
7161D7455B9
可以看到储存在control file中的三个SCN的数值都是相同的,注意此时的stop scn不会是null,而是等于start scn。
再来查询datafile header中的SCN:
SQL> select name, to_char(checkpoint_change#,'XXXXXXXXXXXX') from v$datafile_hea
der where name like '%gisdts01%';
NAME
-------------------------------------------------------------------
TO_CHAR(CHECKPOINT_CHANGE#,'XX
-------------------------------------------------------------------
/gisdata/datafile/gisdts01.dbf
7161D7455B9
当clean shutdown时,checkpoint会进行,并且此时datafile的stop scn和start scn会相同。等我们打开数据库时,oracle会检查datafile header中的start scn和存于control file中的datafile的scn是否相同,如果相同,接着检查start scn和stop scn是否相同,如果仍然相同,数据库会正常启动,否则就需要recovery….等到数据库open后,储存在control file中的stop scn就会恢复为null值,此时表示datafile是open在正常模式下。
如果不正常shutdown(shutdown abort),则mount数据库后,会发现stop scn并不等于其它位置的scn,而是等于null。这表示oracle在shutdown时没有进行checkpoint,下次启动必须进行crash recovery。
原文地址http://blog.chinaunix.net/u/12476/showart.php?id=142021
转载于:https://blog.51cto.com/369258/1354538