[转]oracle scn学习-凯发app官方网站

凯发app官方网站-凯发k8官网下载客户端中心 | | 凯发app官方网站-凯发k8官网下载客户端中心
  • 博客访问: 3977398
  • 博文数量: 536
  • 博客积分: 10470
  • 博客等级: 上将
  • 技术积分: 4825
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-26 14:08
文章分类

全部博文(536)

文章存档

2024年(3)

2021年(1)

2019年(1)

2017年(1)

2016年(2)

2013年(2)

2012年(10)

2011年(43)

2010年(10)

2009年(17)

2008年(121)

2007年(252)

2006年(73)

相关博文
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·

分类: oracle

2007-08-03 11:33:38

scn: system change number

scn是顺序递增的一个数字,在oracle 中用来标识数据库的每一次改动,及其先后顺序。scn的最大值是0xffff.ffffffff。

oracle对scn的管理
单节点的instance中

单节点的instance中,scn值存在sga区,由system commit number latch保护。任何进程要得到当前的scn值,都要先得到这个latch。
rac/ops环境中

oracle通过排队机制(enqueue)实现scn在各并行节点之间的顺序增长。具体有两种方法:

lamport算法:又称面包房算法,先来先服务算法。跟很多银行采用的排队机制一样。客户到了银行,先领取一个服务号。一旦某个窗口出现空闲,拥有最小服务号的客户就可以去空闲窗口办理业务。

commit广播算法:一有commit完成,最新的scn就广播到所有节点中。

上述两种算法可以通过调整初始化参数max_commit_propagation_delay来切换。在多数系统 (除了compaq tur64 unix)中,该参数的默认值都是700厘秒(centisecond),采用lamport算法。如果该值小于100厘秒,oracle就采用广播算法,并且记录在alert.log文件中。
几种重要的scn
commit scn

当用户提交commit命令后,系统将当前scn赋给该transaction。这些信息都反映在redo buffer中,并马上更新到redo log 文件里。
offline scn

除了system tablespace以外的任何表空间,当我们执行sql>alter tablespace … offline normal命令时,就会触发一个checkpoint,将内存中的dirty buffer写入磁盘文件中。checkpoint完成后,数据文件头会更新checkpoint scn和offline normal scn值。其中数据库文件头的checkpoint scn值可通过查询列x$kccfe.fecps得到。

如果执行sql>alter tablespace …offline命令时采用temporary或 immediate选项,而不用normal选项时,offline normal scn会被设成0。这样当数据库重启后通过resetlog方式打开时,该表空间就无法再改回在线状态。
checkpoint scn

当数据库内存的脏数据块(dirty blocks)写到各数据文件中时,就发生一次checkpoint。数据库的当前checkpoint scn值存在x$kccdi.discn中。checkpoint scn在数据库恢复中起着至关重要的作用。无论你用何种办法恢复数据库,只有当各个数据库文件的checkpoint scn都相同时,数据库才能打开。

虽然参数“_allow_resetlogs_corruption”可以在checkpoint scn不一致时强制打开数据库,但是这样的数据库在open后必须马上作全库的export,然后重建数据库并import数据。
resetlog scn

数据库不完全恢复时,在指定时间点后的scn都无法再应用到数据库中。resetlog时的scn就被设成当前数据库scn,redo log也会被重新设置。
stop scn

stop scn记录在数据文件头上。当数据库处在打开状态时,stop scn被设成最大值0xffff.ffffffff。在数据库正常关闭过程中,stop scn被设置成当前系统的最大scn值。在数据库打开过程中,oracle会比较各文件的stop scn和checkpoint scn,如果值不一致,表明数据库先前没有正常关闭,需要做恢复。
high and low scn

oracle的redo log会顺序纪录数据库的各个变化。一组redo log文件写满后,会自动切换到下一组redo log文件。则上一组redo log的high scn就是下一组redo log的low scn。

在视图v$log_history中,sequence#代表redo log的序列号,first_change#表示当前redo log的low scn,列next_change#表示当前redo log的high scn。

sql> col recid format 9999

sql> col requence# format 9999

sql> col first_change# format 9,999,999,999,999

sql> col next_change# format 9,999,999,999,999

sql> select recid,sequence#,first_change#,next_change# from v$log_history where rownum<6;

recid sequence# first_change# next_change#

----- ---------- ------------------ ------------------

484 484 1,928,645,840,091 1,928,645,840,436

485 485 1,928,645,840,436 1,928,645,840,636

486 486 1,928,645,840,636 1,928,778,045,209

487 487 1,928,778,045,209 1,929,255,480,725

488 488 1,929,255,480,725 1,930,752,214,033

关于如何使用参数_allow_resetlogs_corruption,可参见文档

from :

=========================
scn
    scn - system change number - a number, internal to oracle that is incremented over time as change vectors are generated, applied, and written to the redo log.

    scn - system commit number - a number, internal to oracle that is incremented with each database commit.

    system commit numbers and system change numbers share the same internal sequence generator.

eg:
sql> select dbms_flashback.get_system_change_number a from dual;
 
         a
----------
  15503052

sql> select checkpoint_change# a from v$datafile;
 
         a
----------
  15496179
  15496179

=======================
问题的提出:
在并发的环境下,每个sql先执行的不一定先提交,因此想如何才能按照事务提交的顺序来对记录进行排序而不是按照sql执行的时间。

先来说说sysdate或者systimestamp,如果系统中使用这样的列来记录每个记录最后提交的时间,那是错误的。而且很多人认为这个时间如果设置为default值,那么记录的就是sql执行的时间,其实也是错误的。oracle 10.2 版本的concept第388页有这样一句话“default values are included as part of an insert statement before the statement is parsed.”因此可以看到,把列的default值设置为缺省值,或者insert into table(col1...) values (sysdate,...)的方式最后得到的时间都是sql解析的时间而不是sql执行的时间。

ora_rowscn是oracle 10g版本中提出的概念,是一个伪列,用来记录数据提交时候的scn,而scn是唯一的,而且scn的先后就是commit的时间的先后(虽然事务 commit不是导致scn增长的唯一因素)。因此可以按照这个伪列进行排序,得到的结果就是事务提交的先后进行的排序。

默认的建表方式的 ora_rowscn记录的scn是精确到每个block而不是精确到block中的每个row的,因为ora_rowscn取自data block header的scn。要使用此特性需要使用以下方式建表:create table tab(col1 number) rowdependencies。这样就可以为每个列保存自己的scn,需要增加每行数据6个字节的空间的开销。

另外,oracle还提供了ora_rowscn到timestamp的转换,可以得到每个记录最后的修改时间,但这个时间和真正的数据发生变化的时间有误差,误差在正负3秒(引用自tom,是否是因为每3秒scn会刷一次有关呢?有待验证)

this parts from:
阅读(2091) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
")); function link(t){ var href= $(t).attr('href'); href ="?url=" encodeuricomponent(location.href); $(t).attr('href',href); //setcookie("returnouturl", location.href, 60, "/"); }
网站地图