楼主: bellsz

[精华] 关于SCN的理解,请指正

[复制链接]
论坛徽章:
86
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19版主8段
日期:2012-05-15 15:24:112013年新春福章
日期:2013-02-25 14:51:24
21#
发表于 2004-8-14 21:24 | 只看该作者
最初由 lifeng@itpub 发布
[B]澄清几个概念
1)系统当前SCN并不是在任何的数据库操作发生时都会改变,SCN是在事务提交或回滚时改变,

.在定位到底是使用哪一个redo log文件时,就用到了日志文件头中的low scn,next scn,也就是说要使用的redo log 的low scn ,next scn必须包含数据文件重做所须的change vector.

在确定了哪个数据文件须redo后,oracle会比较change vector中的SCN和数据文件数据块中的SCN,如果change vector的SCN小于数据块的scn,则跳过此change vector,否则redo

[/B]


1: SCN 并不仅仅在 提交或者回滚的时候才改变,DML 发生的时候会改变,提交的时候也会变,还有很多的变化都会改变, 有兴趣请去 www.ixora.com.au  看看  。证明的方法也很容易。

2: 在定位到底使用哪个日志文件的时候,并不是用 数据文件中的 low  scn 去框,在日志文件的low scn  and  next  scn 之间就利用该日志文件。而是在数据文件头中有 RBA 的记录,RBA 包含了日志序号、block  number 、slot number  。 这样可以直接定位到日志文件(归档日志文件)和具体的位置

如果你有兴趣,大可去实验,dump出来看看。

使用道具 举报

回复
论坛徽章:
0
22#
发表于 2004-8-15 17:08 | 只看该作者
找了一些网页,发现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增加,也请大家踊跃讨论!

使用道具 举报

回复
论坛徽章:
86
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19版主8段
日期:2012-05-15 15:24:112013年新春福章
日期:2013-02-25 14:51:24
23#
发表于 2004-8-15 17:25 | 只看该作者
最初由 lifeng@itpub 发布
[B]找了一些网页,发现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增加,也请大家踊跃讨论! [/B]


这句话我应该更准确第表达一下

如果一个dml导致产生事务,则会产生一个scn。这个意思是说
如果一个事务包含多个dml,则只有第一个初始产生事务的dml产生scn,提交的时候又是一个scn

如果一个事务只有一个dml,拿看起来就是dml产生一个scn,提交或者回滚产生一个scn


这是经过实验测试过的,如果你又兴趣,不紧紧是要找资料看,还可以动手 证明

使用道具 举报

回复
论坛徽章:
0
24#
发表于 2004-8-16 19:53 | 只看该作者
试验结果确实同所说:

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282673
SQL> insert into test values (1);

已创建一行。

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282674

SQL> insert into test values (2);

已创建一行。

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282674

SQL> commit;

提交完成。

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282678

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

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282684

SQL> insert into test values (1);

已创建一行。

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282685

SQL> rollback;

重算已完成。

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282687



从实验结果看,一个事务中并不是所有的DML操作导致了SCN的增加,只有第一个非SELECT的DML语句导致SCN的增加,因此我认为不是DML本身导致SCN增加,而更有可能是第一个非SELECT的DML语句执行额外的动作(相比较事务中其他语句来说),此额外动作导致了SCN增加。

另外,要注意的是如果一个事务光是SELECT,而不做其它的INSERT,UPDATE操作,即使在COMMIT后,SCN也不会改变。
试验如下:

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282694

SQL> select * from test2;

         N
----------
         1

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282694

SQL> commit;

提交已完成。

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282694

注:
在ORACLE 8I以下,可通过如下语句取得CURRENT SCN
select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;
在ORACLE 9I,使用如下语句取得CURRENT SCN
select dbms_flashback.get_system_change_number from dual;

使用道具 举报

回复
论坛徽章:
86
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19版主8段
日期:2012-05-15 15:24:112013年新春福章
日期:2013-02-25 14:51:24
25#
发表于 2004-8-16 23:05 | 只看该作者
你可以理解为 begin  transaction   and   commit  tansaction   

至于没有dml的commit ,那不叫一个 transaction

你不做任何dml  而发出rollback命令 将会发现 v$sysstat 中 user  rollbacks 将会增加 而 transactions 不会增加


所以你可以把结论定义为 事务的开始 和事务的结束都会导致 SCN 的增加,其他如 AQ/JOB 等也会产生SCN ……
同一个block上在一个事务中连续发生255个DML后scn也会增加
……

使用道具 举报

回复
论坛徽章:
3
授权会员
日期:2006-11-26 10:17:00生肖徽章2007版:鸡
日期:2008-01-02 17:35:532011新春纪念徽章
日期:2011-02-18 11:42:47
26#
发表于 2005-7-31 13:46 | 只看该作者
为什么在9i里面按照上面大哥指点的做试验却是一次就增加几百呢!

使用道具 举报

回复
论坛徽章:
3
授权会员
日期:2006-11-26 10:17:00生肖徽章2007版:鸡
日期:2008-01-02 17:35:532011新春纪念徽章
日期:2011-02-18 11:42:47
27#
发表于 2005-7-31 13:48 | 只看该作者
SQL> select dbms_flashback.get_system_change_number from dual;

GET_SYSTEM_CHANGE_NUMBER
------------------------
                  971777

SQL> insert into test values(1);

已创建 1 行。

SQL> select dbms_flashback.get_system_change_number from dual;

GET_SYSTEM_CHANGE_NUMBER
------------------------
                  972342

使用道具 举报

回复
论坛徽章:
3
授权会员
日期:2006-11-26 10:17:00生肖徽章2007版:鸡
日期:2008-01-02 17:35:532011新春纪念徽章
日期:2011-02-18 11:42:47
28#
发表于 2005-7-31 13:55 | 只看该作者
呵呵上面的帖子都是一年前的了,我是按照biti的建议先把精华贴子看看!
心里面急呀!

使用道具 举报

回复
论坛徽章:
9
ITPUB8周年纪念徽章
日期:2009-09-27 10:21:21ITPUB9周年纪念徽章
日期:2010-10-08 09:32:272011新春纪念徽章
日期:2011-02-18 11:43:352012新春纪念徽章
日期:2012-01-04 11:49:54ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:372013年新春福章
日期:2013-02-25 14:51:242014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11马上有房
日期:2014-05-15 09:09:06
29#
发表于 2005-10-12 20:54 | 只看该作者
to:biti_rainy

最初由 biti_rainy 发布
[B]

这句话我应该更准确第表达一下

如果一个dml导致产生事务,则会产生一个scn。这个意思是说
如果一个事务包含多个dml,则只有第一个初始产生事务的dml产生scn,提交的时候又是一个scn

如果一个事务只有一个dml,拿看起来就是dml产生一个scn,提交或者回滚产生一个scn


这是经过实验测试过的,如果你又兴趣,不紧紧是要找资料看,还可以动手 证明 [/B]


如果一个事务包含多个dml,当执行到某一个时出现检查点,那么下一条dml也应产生SCN吧。顺便问一句redo log中的 redo record中
也应包含一个SCN,而且是该dml执行时产生的SCN

使用道具 举报

回复
论坛徽章:
9
ITPUB8周年纪念徽章
日期:2009-09-27 10:21:21ITPUB9周年纪念徽章
日期:2010-10-08 09:32:272011新春纪念徽章
日期:2011-02-18 11:43:352012新春纪念徽章
日期:2012-01-04 11:49:54ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:372013年新春福章
日期:2013-02-25 14:51:242014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11马上有房
日期:2014-05-15 09:09:06
30#
发表于 2005-10-12 21:41 | 只看该作者
最初由 lifeng@itpub 发布
[B]试验结果确实同所说:

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282673
SQL> insert into test values (1);

已创建一行。

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282674

SQL> insert into test values (2);

已创建一行。

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282674

SQL> commit;

提交完成。

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282678

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

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282684

SQL> insert into test values (1);

已创建一行。

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282685

SQL> rollback;

重算已完成。

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282687



从实验结果看,一个事务中并不是所有的DML操作导致了SCN的增加,只有第一个非SELECT的DML语句导致SCN的增加,因此我认为不是DML本身导致SCN增加,而更有可能是第一个非SELECT的DML语句执行额外的动作(相比较事务中其他语句来说),此额外动作导致了SCN增加。

另外,要注意的是如果一个事务光是SELECT,而不做其它的INSERT,UPDATE操作,即使在COMMIT后,SCN也不会改变。
试验如下:

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282694

SQL> select * from test2;

         N
----------
         1

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282694

SQL> commit;

提交已完成。

SQL> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;

MAX(KTUXESCNW*POWER(2,32)+KTUXESCNB)
------------------------------------
                              282694

注:
在ORACLE 8I以下,可通过如下语句取得CURRENT SCN
select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;
在ORACLE 9I,使用如下语句取得CURRENT SCN
select dbms_flashback.get_system_change_number from dual; [/B]


为什么什么都不做每隔几秒中查询的SCN会发生变化?是检查点的原因吗?

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表