关于SCN

| 2 Comments

403e里这样描述SCN

The SCN marks consistent states of the database associated with transaction commits.

The SCN also serves as a means of ordinance and acts as an internal clock. Each database has a global SCN generator. 

Almost every time that a new SCN is calculated, there is a verification that the new value is "reasonable," that is, inferior to a theoretical maximum value based on the hypothesis that there cannot be more than 16,384 commits per second.

SCNs are used for concurrency control (read consistency), redo log records ordering, and recovery.

The SCN base (4 bytes) is incremented for each SCN allocation. The SCN wrap (2 bytes) is incremented when the base turns over.

SCN numbers are monotonically increasing, but they may jump in a distributed or parallel server environment.

 

看到这里,我脑海里会浮现这样几个问题:

1、  按照上述理论----cannot be more than 16,384 commits per secondoracle里的SCN能用多少年?

2、  大家都知道,利用公式scn_wrap*4294967296+scn_bas就可以将oracle存储在物理文件里的SCN转换成我们熟悉的以数字形式表示的SCN,这个公式是如何得到的?

 

对于问题一:

每秒16384commit即代表每秒会产生16384SCNSCN6byte,我们按照一个月31天来计算,上述6byteSCN在每秒16384commit强度的情况下一共可以持续的年份的计算方法就一目了然了:

SQL> select power(16,12)/(16384*60*60*24*31*12) years from dual;

 

 YEARS

----------

534.519028

也就是说,在每秒16384commit的情况下可以维持534

 

那上述SCN的终点具体是哪一年呢?这还要从oracle里用数字来代表时间的算法说起,对这一点403e里也有叙述:

Timestamps exist in the file headers and in many control file sections. These timestamps are not the same format as DATE or TIMESTAMP but contain a simple integer with the number of seconds since 1/1/1988.

 

从这里我们就可以知道上述SCN的终点是2522

SQL> select 1988+534 last_year from dual;

 

 LAST_YEAR

----------

      2522

 

 

对于问题二:

我们先来看一个实际的转换的例子:

484489byte,如下图所示:

File: /iprat02/ipratest/system01.dbf (1)

 Block: 1                Offsets:    0 to  511           Dba:0x00400001

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

 0ba20000 00400001 00000000 00000104 0bb20000 00000000 0a200100 5091aeb3

 49505241 54455354 0000329d 0000f000 00002000 00010003 00000000 00000000

 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

 00400179 00000008 00000000 21a23e84 28144e35 00086983 0000000a 00000000

 00000000 00000000 00002004 00000156 28144e27 00000155 00000000 00000000

 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

 00000000 00000000 00000000 00000000 00065359 5354454d 00000000 00000000

 00000000 00000000 00000000 00000000 00000001 00000000 00000000 00000000

 00000000 00005480 00000000 00000000 00000000 00000000 00000000 000a000a

 21a23e71 00000001 00000000 00000000 00000000 00000000 00000000 00000000

 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

 00000000 d0d59fee 000bd5c4 29797a28 00019268 000000c4 00000002 00100001

 

 <32 bytes per line>

d0d59fee 000b表示为X$KCVFH中的FHSCN,表示CHECKPOINT_CHANGE#, Datafile checkpoint change#, Updated on every checkpoint, but not when in Hot backup state (not online backups). This must remain untouched when you are in hot backup mode, because you might get checkpoints between the BEGIN BACKUP and when you actually start the copying process.d0d59feescn base000bscn wrap.

 

这里的CHECKPOINT_CHANGE#d0d59fee 000b,利用公式scn_wrap*4294967296+scn_bas就可以将其转换成我们熟悉的SCN,过程如下:

SQL> select to_number('b','XXXX') from dual;

 

TO_NUMBER('B','XXXX')

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

                   11

 

SQL> select to_number('d0d59fee','XXXXXXXX') from dual;

 

TO_NUMBER('D0D59FEE','XXXXXXXX

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

                    3503661038

 

SQL> select 11*4294967296+3503661038 from dual;

 

11*4294967296+3503661038

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

             50748301294

 

SQL> select scn_to_timestamp(50748301294) from dual;

 

SCN_TO_TIMESTAMP(50748301294)

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

25-8 -09 01.16.22.000000000 下午

 

朋友们明白为什么这里要乘4294967296吗?

其实403e里已经用如下这段话解释清楚了----The SCN base (4 bytes) is incremented for each SCN allocation. The SCN wrap (2 bytes) is incremented when the base turns over.

 

也就是说当4byteSCN base满了后就将SCN base0,同时在SCN wrap上加1,周而复始,这就是上面那段话里"turns over"的含义。

 

SCN base4byte,也就是168次方:

SQL> select power(16,8) from dual;

 

POWER(16,8)

-----------

 4294967296

这就是4294967296的来历。

 

关于SCNtime的互相转换,10g里可以用scn_to_timestamp()timestamp_to_scn()9i里只能用smon_scn_time来估算5天以内的互换。

2 Comments

如何知道SCN是存放在第484-489个byte的呢?

你在BBED里执行p kcvfh就知道checkpoint scn的具体位置了。

Leave a comment