1.oracle正常运行时,control文件的SCN是个很大的数,与redo log文件、数据文件的SCN不一样,正常关闭时,作完checkpoint后,三者的SCN值相同;
Biti:日志文件中scn有起始和结束2个(高低),在current log中高scn一样为无穷大。
2.当一个事务commit成功时,redo log文件中的SCN+1,当该事务所作的修改写入数据文件后,数据文件的SCN+1;
Biti:commit的时候加1,其余不少时候也会加1,只要数据库发生了变化都会增长。数据写入数据文件时scn不是加1而是由ckpt更新,检查点发生的时候才修改数据文件头的检查点计数并更新scn。
3.疑问:
是否是若是一个事务比较大,在事务提交前就发生redo log entries、data buffer的写入,此时断电,则数据文件、redo log文件的SCN没有+1,且相同,但控制文件SCN不一样,数据库startup时发生回滚。
Biti:数据文件是由ckpt进程更新文件头的,scn不是加1,而是更新为检查点发生那时的scn,回滚是根据回滚段头的事务表状态来进行的。html
4.数据写入数据文件scn不是加1而是ckpt 更新,检查点发生的时候才修改数据文件头的检查点计数和更新scn
是否是应该这么说?:
当ckpt 更新时发生数据写入,同时修改数据文件头的检查点计数和更新scn 。当出现其余状况下的数据写入时(如无空闲缓冲等),不发生ckpt ,但SCN会增长。
Biti:这个时候修改的是数据块但不是数据文件头,只有检查点发生的时候才更新数据文件头,也就是说只有ckpt进程更新数据文件头(oracle8之前若是没有ckpt进程就是lgwr更新),dbwr只写数据块。数据库
BTW:看样DBWR只是些数据块,只有CKPT进程才能更新数据文件头;
5.commit的时候加一,其余不少时候也会加1,只要数据库发生了变化都会增长。
不少时候,可否举一些例子
Biti: dml一发生即便没有提交也会增长scn, job进程同样产生scn,只要对数据库中文件发生任何的改变都有可能产生scn,SCN: system change number, not system commit number .也就是系统发生变化时所产生的一个时间点安全
标志。不是提交的标志,只是由于提交也是系统的变化之一而已。oracle
6.Biti:检查点的发生,跟写日志文件是没有必然联系的
检查点通知 DBWR 写数据文件,写完后ckpt更新控制文件头和数据文件头。
当DBWR写数据块的时候若发现数据块的相关 RDBA (位于日志文件的位置) 的 log block 尚未被写入日志文件,则在dbwr写块以前必须通知lgwr把log buffer 中日志写入日志文件。dom
7.data block 里面的SCN是当 block 被更改的时候的SCN
而数据文件有那么多 block,天然不一样的 block有不一样的SCN
block中存在 block SCN 和 ITL 中的commit SCN
block SCN 又在块头和块尾都有,若不一致意味着block损坏(热备可能出现这个状况,须要从redo log中拷贝回来,如果正在修改的过程当中因为进程死掉则 pmon负责清理。若因为一些之外发生这样的不一致的状况,则查询的时候出现 1578 错误,固然该错误号也多是物理磁盘损坏,这里表示逻辑的损坏!)这个头和尾的SCN的检查时机跟这两个参数有关:
db_block_checking boolean FALSE
db_block_checksum boolean FALSE
该2参数信息请查阅http://tahiti.oracle.com
而ITL 中的 commit SCN 则跟 consistent gets and delay block cleanout 有关
数据文件头的 SCN 是检查点发生时更新的
表明着当恢复的时候从这个 SCN 点开始在 log file 中寻找 redo 开始作恢复ide
8.According to Rama Velpuri's book, CKPT updates controlfiles, not their headers. It makes sense because if you look at a controlfile dump, the header doesn't even have an SCN. But the file body has sections for each datafile, and therefore each of them has an SCN to be updated.
It's odd that most books and also documentation don't even say CKPT updates controlfiles.
Follow-up to bellsz's original message. In controlfiles, the stop SCN is not a very big number; it's in fact set to infinity when the database is open. Also, SCNs are incremented for many reasons, mostly due to recursive transactions. Read Steve Adams and Hemant Chitale's answers at
http://groups.google.com/groups?sel...t_nospam.com.sg
9.测试
系统检查点scn(v$database(checkpoint_change#))
数据文件检查点(v$datafile(checkpoint_change#))
数据文件终止scn(v$datafile(last_change#))
数据文件中存放的检查点
启动scn (v$datafile_header(checkpoint_change#)
1>系统检查点scn
当一个检查点动做完成以后,Oracle就把系统检查点的SCN存储到控制文件中。
select checkpoint_change# from v$database
2>数据文件检查点scn
当一个检查点动做完成以后,Oracle就把每一个数据文件的scn单独存放在控制文件
中。
select name,checkpoint_change# from v$datafile
3>启动scn
Oracle把这个检查点的scn存储在每一个数据文件的文件头中,这个值称为启动scn,
由于它用于在数据库实例启动时,检查是否须要执行数据库恢复。
select name,checkpoint_change# from v$datafile_header
4>终止scn
每一个数据文件的终止scn都存储在控制文件中。
select name,last_change# from v$datafile
在正常的数据库操做过程当中,全部正处于联机读写模式下的数据文件的终止scn都为null.
5>在数据库运行期间的scn值
在数据库打开并运行以后,控制文件中的系统检查点、控制文件中的数据文件检查点scn
和每一个数据文件头中的启动scn都是相同的。控制文件中的每一个数据文件的终止scn都为null.
在安全关闭数据库的过程当中,系统会执行一个检查点动做,这时全部数据文件的终止scn
都会设置成数据文件头中的那个启动scn的值。在数据库从新启动的时候,
Oracle将文件头中的那个启动scn与数据库文件检查点scn进行比较,
若是这两个值相互匹配,oracle接下来还要比较数据文件头中的启动scn和控制文件
中数据文件的终止scn。若是这两个值也一致,就意味着全部数据块多已经提交,全部
对数据库的修改都没有在关闭数据库的过程当中丢失,所以此次启动数据库的过程
也不须要任何恢复操做,此时数据库就能够打开了。当全部的数据库都打开以后,
存储在控制文件中的数据文件终止scn的值再次被更改成null,
这表示数据文件已经打开并可以正常使用了。this
10.google
找了一些网页,发现SCN确实不仅在事务提交时增长,如下是网页上的摘要:
1)
SCN means "System Change Number" not "System Commit Number".
However, because the SCN is always incremented at commits and seldom otherwise, it is OK to use the two terms interchangeably.
2)
The SCN is incremented whenever a transaction commits. However, this is not the only source of increments. In a seemingly idle database, the SCN gets incremented also through AQ, SMON, job queues...
1中说了 oracle seldom操做也会引发SCN的增长,2中更明确说了AQ, SMON, job queues... 会致使SCN的增长,所以应该得出结论,在ORACLE中除了COMMIT会致使SCN增长外还有其它的ORACLE后台进程会致使SCN增长.
可是,是不是普通的DML致使了SCN的增长,仍是因为DML操做过程当中后台进程致使了SCN增长的假象?请你们踊跃讨论!
还有ORACLE后台进程在什么时候,何种状况下致使了SCN增长,也请你们踊跃讨论!spa
Biti:这句话我应该更准确第表达一下
若是一个dml致使产生事务,则会产生一个scn。这个意思是说
若是一个事务包含多个dml,则只有第一个初始产生事务的dml产生scn,提交的时候又是一个scn
若是一个事务只有一个dml,拿看起来就是dml产生一个scn,提交或者回滚产生一个scn
这是通过实验测试过的,若是你又兴趣,不牢牢是要找资料看,还能够动手证实。
你能够理解为 begin transaction and commit tansaction
至于没有dml的commit ,那不叫一个 transaction
你不作任何dml 而发出rollback命令将会发现 v$sysstat 中 user rollbacks 将会增长而 transactions 不会增长
因此你能够把结论定义为事务的开始和事务的结束都会致使 SCN 的增长,其余如 AQ/JOB 等也会产生SCN ……
同一个block上在一个事务中连续发生255个DML后scn也会增长
……
11.sys@DBAP01> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;
MAX(KTUXESCNW*POWER(2,32)+KTUX
------------------------------
52211024
已用时间: 00: 00: 00.00
sys@DBAP01> alter system checkpoint;
系统已更改。
已用时间: 00: 00: 00.06
sys@DBAP01> select CHECKPOINT_CHANGE# from v$database;
CHECKPOINT_CHANGE#
------------------
52211055
已用时间: 00: 00: 00.00
sys@DBAP01> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;
MAX(KTUXESCNW*POWER(2,32)+KTUX
------------------------------
52211053
x$ktuxe 计算出来的是已经结束的最新的事务的commit scn ,因此可小于当前系统scn。检查点scn 天然也小于当前系统scn。可是检查点scn 和 x$ktuxe 计算出来的大小却倚赖于系统情况了。
current scn 是系统当前所产生的最大 scn ,多是当前未结束事务所产生的scn。在9i 的dbms_flashback.get_system_change_number能够获得这个值,这个值应该是大于等于 x$ktuxe SCN (这个view 记录的是当前数据库结束事务的最大scn)