Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Saibabu.

Asked: April 25, 2003 - 7:47 pm UTC

Last updated: March 22, 2012 - 4:57 pm UTC

Version: 9.2

Viewed 10K+ times! This question is

You Asked

Hi Tom,

1) What is difference between SCN base and SCN wrap. What for SCN wrap is used. I always see SCN wrap zero in v$transaction.

2)I have a small table and all of its data fit in one data block. From one session this table was modified without commit or rollback, from second session after some time select query was issued on this table. How does Oracle find block was modified but not commited especially when second session scn is greater than first session scn?

3)How does Oracle find which block buffer image to use for Current mode/read consistent mode when we have several images of same block in buffer cache? Was there any change in this behaviour in Oracle 9.2 compared to 8.1.7.

Thanks
Sai.

and Tom said...

1) SCNs are just numbers. Think of the base and the wrap as a way to store an even bigger number -- The wrap is incremented whenever an increment to the base would result in an overflow (when the SCN would roll over to zero again).

It will not always be zero, just depends on how many wraps you've done (roll overs if you will)

ps$tkyte@ORA817DEV> select start_scnw, start_scnb from v$transaction;

START_SCNW START_SCNB
---------- ----------
1683 4117418604



2) see

</code> http://docs.oracle.com/cd/A87860_01/doc/server.817/a76965/c23cnsis.htm#17882 <code>

we use undo data to provide consistent reads

3) we use the SCN and find the block that would be "most correct" -- the newest block with the SCN greater than or equal to the SCN that was in place when your transaction began. The rollback segments give us this information. It is pretty much the same in 9iR2 as it was in 8i, 8.0, 7.x, 6.x... tweaks and optimizations but fundementally the same.


Rating

  (40 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

SCN base and wrap.

Sai, April 29, 2003 - 1:04 am UTC

Hi Tom,

I am wondering why we have only one column checkpoint_change# in v$database & v$datafile, and two columns start_scnb & start_scnw in v$transaction(also in block header).

Does it make sense to assume that last checkpoint SCN checkpoint_change# from v$database is close to start_scnb plus some factor multiplied by start_scnw(presuming that checkpoint occured right after current session DML statement started). If I am wrong here, please explain how current start_scnb & start_scnw will be used to arrive at complete SCN number.

Tom Kyte
April 29, 2003 - 8:02 am UTC

use dbms_flashback to get the only SCN you ever need to know.

Segment header.

Saibabu Devabhaktuni, May 21, 2003 - 2:13 am UTC

Hi Tom,
When we issue insert statement, Oracle will scan through freelist (intermediate BMB blocks and leaves in automatic segment space management). How can we find how many blocks are being used for segment extent maps(intermediate BMB and leave blocks in automatic segment space management)?

Thanks

Tom Kyte
May 21, 2003 - 8:31 am UTC

you can derive this value.


Using a procedure like this, we can get details:


ops$tkyte@ORA920> create or replace procedure show_space
  2  ( p_segname in varchar2,
  3    p_owner   in varchar2 default user,
  4    p_type    in varchar2 default 'TABLE',
  5    p_partition in varchar2 default NULL )
  6  authid current_user
  7  as
  8      l_free_blks                 number;
  9
 10      l_total_blocks              number;
 11      l_total_bytes               number;
 12      l_unused_blocks             number;
 13      l_unused_bytes              number;
 14      l_LastUsedExtFileId         number;
 15      l_LastUsedExtBlockId        number;
 16      l_LAST_USED_BLOCK           number;
 17      l_segment_space_mgmt        varchar2(255);
 18      l_unformatted_blocks number;
 19      l_unformatted_bytes number;
 20      l_fs1_blocks number; l_fs1_bytes number;
 21      l_fs2_blocks number; l_fs2_bytes number;
 22      l_fs3_blocks number; l_fs3_bytes number;
 23      l_fs4_blocks number; l_fs4_bytes number;
 24      l_full_blocks number; l_full_bytes number;
 25
 26      procedure p( p_label in varchar2, p_num in number )
 27      is
 28      begin
 29          dbms_output.put_line( rpad(p_label,40,'.') ||
 30                                to_char(p_num,'999,999,999,999') );
 31      end;
 32  begin
 33    select ts.segment_space_management
 34      into l_segment_space_mgmt
 35      from dba_segments seg,  dba_tablespaces  ts
 36     where seg.segment_name    = p_segname
 37       and   seg.owner           = p_owner
 38       and   seg.tablespace_name = ts.tablespace_name;
 39
 40    if l_segment_space_mgmt = 'AUTO'
 41    then
 42       dbms_space.space_usage (
 43         p_owner,
 44         p_segname,
 45         p_type,
 46         l_unformatted_blocks,
 47         l_unformatted_bytes,
 48         l_fs1_blocks, l_fs1_bytes,
 49         l_fs2_blocks, l_fs2_bytes,
 50         l_fs3_blocks, l_fs3_bytes,
 51         l_fs4_blocks, l_fs4_bytes,
 52         l_full_blocks, l_full_bytes
 53       );
 54       --
 55       p( 'Unformatted Blocks ', l_unformatted_blocks );
 56       p( 'FS1 Blocks (0-25)  ', l_fs1_blocks );
 57       p( 'FS2 Blocks (25-50) ', l_fs2_blocks );
 58       p( 'FS3 Blocks (50-75) ', l_fs3_blocks );
 59       p( 'FS4 Blocks (75-100)', l_fs4_blocks );
 60       p( 'Full Blocks        ', l_full_blocks );
 61    else
 62       dbms_space.free_blocks(
 63         segment_owner     => p_owner,
 64         segment_name      => p_segname,
 65         segment_type      => p_type,
 66         freelist_group_id => 0,
 67         free_blks         => l_free_blks
 68       );
 69       --
 70       p( 'Free Blocks', l_free_blks );
 71    end if;
 72      dbms_space.unused_space
 73      ( segment_owner     => p_owner,
 74        segment_name      => p_segname,
 75        segment_type      => p_type,
 76            partition_name    => p_partition,
 77        total_blocks      => l_total_blocks,
 78        total_bytes       => l_total_bytes,
 79        unused_blocks     => l_unused_blocks,
 80        unused_bytes      => l_unused_bytes,
 81        LAST_USED_EXTENT_FILE_ID => l_LastUsedExtFileId,
 82        LAST_USED_EXTENT_BLOCK_ID => l_LastUsedExtBlockId,
 83        LAST_USED_BLOCK => l_LAST_USED_BLOCK );
 84
 85      p( 'Total Blocks', l_total_blocks );
 86      p( 'Total Bytes', l_total_bytes );
 87      p( 'Total MBytes', trunc(l_total_bytes/1024/1024) );
 88      p( 'Unused Blocks', l_unused_blocks );
 89      p( 'Unused Bytes', l_unused_bytes );
 90      p( 'Last Used Ext FileId', l_LastUsedExtFileId );
 91      p( 'Last Used Ext BlockId', l_LastUsedExtBlockId );
 92      p( 'Last Used Block', l_LAST_USED_BLOCK );
 93  end;
 94  /

Procedure created.

ops$tkyte@ORA920> set define on
ops$tkyte@ORA920> exec show_space( 'T' )
Unformatted Blocks .....................               0
FS1 Blocks (0-25)  .....................               0
FS2 Blocks (25-50) .....................               0
FS3 Blocks (50-75) .....................               0
FS4 Blocks (75-100).....................               0
Full Blocks        .....................             411
Total Blocks............................             512
Total Bytes.............................       4,194,304
Total MBytes............................               4
Unused Blocks...........................              85
Unused Bytes............................         696,320
Last Used Ext FileId....................               8
Last Used Ext BlockId...................             392
Last Used Block.........................              43

PL/SQL procedure successfully completed.


<b>that shows there are 411 "data" blocks, blocks with data on them.  There are 512 total blocks in the segment -- 85 of which are totally unused (above the real HWM, not touched).

Well, 512 - 411 - 85 = 16, there are 16 blocks "unaccounted for".  they are used by Oracle to manage this segment.</b>
 

OK

Siva, August 09, 2004 - 1:56 am UTC

Dear Tom,
Is there any relationship between SCN and Checkpoint?

Tom Kyte
August 09, 2004 - 7:50 am UTC

scn = the Oracle clock, a ticker

a checkpoint is the act of flushing out dirty blocks from the buffer cache. It happens at a "time", time in Oracle is measured by the SCN.


so sort of, in as much as a checkpoint happens at a point in time, stamps file headers with that time.


but "not really", "not directly".

When did an SCN occur?

AR, August 19, 2004 - 10:52 pm UTC

Tom,
Is it possible to tell the exact time that an SCN was generated in the past? (Yes, v$archived_log helps us narrow it down to something "between" 2 timestamps) Or is logminer the way to go for that?

Thank you for your time.

Tom Kyte
August 19, 2004 - 10:55 pm UTC

in 9i, within +/- 5 minutes
in 10g, withing +/- 3 seconds

otherwise -- no, not really.

When did the SCN occur

AR, August 19, 2004 - 11:11 pm UTC

Tom,
> in 9i, within +/- 5 minutes

I'm sorry, but I don't understand. How do you do this?

Thank you.

Tom Kyte
August 20, 2004 - 10:36 am UTC

sys@ORA9IR2> desc smon_scn_time
Name Null? Type
---------------------------------------- -------- ----------------------------
THREAD NUMBER
TIME_MP NUMBER
TIME_DP DATE
SCN_WRP NUMBER
SCN_BAS NUMBER

sys@ORA9IR2> select * from smon_scn_time where rownum <= 5;

THREAD TIME_MP TIME_DP SCN_WRP SCN_BAS
---------- ---------- --------- ---------- ----------
1 1101509976 23-JUL-04 0 26145657
1 1101542535 23-JUL-04 0 26145703
1 1101553388 23-JUL-04 0 26145719
1 1103995610 23-JUL-04 0 26147989

......

that table (owned by sys) keeps a mapping of time ranges to scn's -- really if you need this to be 'accurate', you'll be using logminer.

In 10g there is a function that converts an scn into time within 3 seconds.

Re: When did the SCN occur

Sai, August 20, 2004 - 12:25 am UTC

I guess there is an object like SMON_SCN_TIME in 9i that would give SCN for every 5 mimutes.

Tom, how can we find SCN +/- 3 secs in 10g?

Thanks.

Tom Kyte
August 20, 2004 - 10:44 am UTC

there is a function scn_to_timestamp provided.

Segement Header

John Spencer, August 20, 2004 - 9:55 am UTC

Tom:

In the show_space followup, you say that:

Total Blocks - Full Blocks - Unused Blocks = Segment Management Blocks

When I run this I get some blocks in FS1 and FS4 Blocks. Are these also counted in Full Blocks, or do I needto add them to Full Blocks to find the Segment Management Blocks. In my case its only 51 block, so I don't really care, just curious.

Thanks
John

Tom Kyte
August 20, 2004 - 8:24 pm UTC

that is ASSM, ASSM is different. there some blocks are used in the interior for space mgmt as well.

unformatted, fs1..fs4 and full blocks are ones you have use of.

Nadeesh, May 06, 2005 - 3:50 am UTC

Tom,

In v$database

CONTROLFILE_CHANGE# is:
Last change number in backup control file (null if the control file is not a backup)

Can you clarify thay what is "backup control file" because I am viewing information from current control file.


Tom Kyte
May 06, 2005 - 7:58 am UTC

that doesn't look right, i'll file a documentation bug on that. thanks

CONTROLFILE_CHANGE# in v$database

Nadeesh, May 07, 2005 - 2:56 am UTC

Tom,

Still, can you please clarify that what is CONTROLFILE_CHANGE# and when it changes its value, because I tried and its value doesn't change on commit.

Regards,

Tom Kyte
May 07, 2005 - 8:06 am UTC

alter system checkpoint and check it out then.

How does scn_to_timestamp get the 3 + - accuracy

A reader, October 30, 2006 - 2:24 pm UTC

Hi Tom please,
Tracing scn_to_timestamp I got only a

select time_mp, scn, num_mappings, tim_scn_map, orig_thread
from SYS.smon_scn_time where scn =
(select max(scn) from SYS.smon_scn_time where thread=0 and scn <= :1)
and thread=0;

how does Oracle get 3 +/- acurracy then. if sys.smon_scn_time is still calling the smon_scn_time which store with a +/- 5 minutes of acurracy.

I suppose it is only an estimate.

Thank you.

Tom Kyte
October 30, 2006 - 3:14 pm UTC


sys%ORA9IR2> desc smon_scn_time;
Name Null? Type
---------------------------------------- -------- ----------------------------
THREAD NUMBER
TIME_MP NUMBER
TIME_DP DATE
SCN_WRP NUMBER
SCN_BAS NUMBER


that was 9i, it was "5 minutes" plus or minus back then. Now the table is:


sys%ORA10GR2> desc smon_scn_time;
Name Null? Type
---------------------------------------- -------- ----------------------------
THREAD NUMBER
TIME_MP NUMBER
TIME_DP DATE
SCN_WRP NUMBER
SCN_BAS NUMBER
NUM_MAPPINGS NUMBER
TIM_SCN_MAP RAW(1200)
SCN NUMBER
ORIG_THREAD NUMBER



see that raw field - that would be the +-3 second stuff, they just "hacked" it into the table

A reader, October 30, 2006 - 4:39 pm UTC

Thanks Tom, I supposed that because It has a lot of data on it, but could you please explain how the data is encoded in this field, plus the description of the others, please, if possible, so I could create a function table to get all the data.
Thanks.

THREAD NUMBER
TIME_MP NUMBER
TIME_DP DATE
SCN_WRP NUMBER
SCN_BAS NUMBER
NUM_MAPPINGS NUMBER
TIM_SCN_MAP RAW(1200)
SCN NUMBER
ORIG_THREAD NUMBER

Tom Kyte
October 30, 2006 - 6:46 pm UTC

we interact with this data via functions - WE do not query this data directly.

WE have no need of knowing "how" it is encoded, we have API's to get at it.

A reader, October 31, 2006 - 8:07 am UTC

Thank you

SCNs ?

parag j patankar, March 30, 2007 - 6:12 am UTC

Hi Tom,

From which are the places and views we can see SCNs for e.g. I can think of alert, v$transaction, dbms_flashback ... etc ?

thanks & regards
PJP
Tom Kyte
March 30, 2007 - 1:35 pm UTC

what are you looking for exactly. They appear in numerous views, yes, and I'm not going to list them all (you can query all-tab_columns like '%SCN%' to see a pretty good list

block scn

A reader, July 02, 2007 - 2:24 am UTC

Hi,Mr. Tom
Could you tell me what's mean of block scn?
Is there exist a scn for a block? or it means the scn of the rows on the block?
but if the latter is true,witch scn of the rows is called block scn? or there never is a block scn?
When oracle do a consistant read ,oracle will check the block scn,it means oracle check the rows scn that matched the query?
Thanks very much if you will kindly give a explain!
Tom Kyte
July 03, 2007 - 9:38 am UTC

a block 'conceptually' has an SCN associated with it. In reality, there is transaction information in the block header that in conjunction with the rollback/undo segment information can be used to derive all of the necessary information.


multi-versioning is done at the block level, when oracle retrieves a block in response to a query - it will ensure the block is old enough AND THEN process any rows on it.

block scn

A reader, July 26, 2007 - 1:42 am UTC

Guess a block have 5 rows values is :
1
2
3
4
5
and there is a trasaction on row 3 after the query,but the query is want the row 5.
So when the query begin process this block , as you metioned,
multi_version is block level ,does oracle know if it fetch the row from the block or from the rbs¿
Best Regards¿
Alan

Tom Kyte
July 27, 2007 - 8:24 am UTC

oracle is asked to get a block

we look at the block and see if the version of the block is "old enough"

if so - you get the block and then retrieve the row

if not, we roll back the block until it is and then you get the block and then retrieve the row

muti_version

A reader, July 27, 2007 - 11:40 pm UTC

Thanks ,Tom!
So in this case,even the row 5 which query needed was not changed after the query started,oracle also will go to the rbs and find the row 3's before image and then scan all rows on the block and get row 5?
Regards!
Alan
Tom Kyte
July 28, 2007 - 9:27 am UTC

Oracle will put the BLOCK (not rows, stop thinking rows, just thing BLOCK) back the way it was.

Yes.

muti_version

A reader, July 28, 2007 - 10:26 pm UTC

Again,many thank¿GREAT TOM!

Limit on SCN value

A reader, December 11, 2007 - 2:50 pm UTC

Tom,
Is there any limit on SCN value? It is like clock ticking and obviously as long as the database is up and running it is gonna keep rising forever...How does oracle take care of this?
Will the value ever get reset? Or is it infinite?

Thanks for your time in advance.

Anybody else Please

A reader, December 17, 2007 - 7:12 pm UTC

If anybody who reads this happens to know the answer for this please help.
Tom Kyte
December 18, 2007 - 1:18 pm UTC

the scn is a 48 bit number

ops$tkyte%ORA11GR1> set numformat 999,999,999,999,999,999,999,999
ops$tkyte%ORA11GR1> select power(2,48) from dual;

                     POWER(2,48)
--------------------------------
             281,474,976,710,656



it is rather huge. even at 1,000 transactions per second - forever - it is unlikely to be encountered

ops$tkyte%ORA11GR1> select power(2,48)/1000/60/60/24/366 from dual;

   POWER(2,48)/1000/60/60/24/366
--------------------------------
                           8,901


Good

A reader, December 18, 2007 - 9:31 pm UTC

Thanks Tom,
Yes,It makes sense.

DBA from India, June 11, 2008 - 12:30 pm UTC

Tom, 
I created the procedure show_space in database. Procedure was created without any errors. But when I try to use it getting following error..

SQL> set define on
SQL> exec show_space('T');
BEGIN show_space('T'); END;

      *
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'SHOW_SPACE' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

Tom Kyte
June 11, 2008 - 4:02 pm UTC

SQL> desc show_space

prove to us you created it. If describe doesn't see it, it isn't there.

versions between "FLUSH results!"

Sallal, December 22, 2009 - 2:12 pm UTC

Hi tom,
i logged in SCOTT user and modify the EMP table more than 3 times and on each i do the COMMIT , then execute the following statement:

SELECT versions_startscn, versions_starttime,
versions_endscn, versions_endtime,
versions_xid, versions_operation,
emp.*
FROM emp
VERSIONS BETWEEN SCN minvalue and maxvalue
where empno=7788;

and the result appeared....
after 20 minutes i execute it again but the old changes no longer exists ?? why?

Tom Kyte
December 31, 2009 - 8:38 am UTC

possibility #1.....

your undo retention is tiny and the data no longer exists.


I'll go with that.


<quote>
Specify BETWEEN SCN ... to retrieve the versions of the row that existed between two SCNs. Both expressions must evaluate to a number. MINVALUE and MAXVALUE resolve to the SCN of the oldest and most recent data available, respectively.
</quote>


the data of 20 minutes ago is simply not available anymore - you didn't ask us to keep it that long.

About SCN

Sathish Kumar, March 23, 2010 - 10:51 am UTC

Hi,Tom
As i know whenever change in database like insert,update,delete SCN is generated.
But in my PC(Dedicated server) when i selected Current_scn from V$Database i found scn is going on changing every second without any insersor updates?
Why? How oracle differentiates commited and uncommited data.
What is current_scn in V$database?
Tom Kyte
March 23, 2010 - 12:51 pm UTC

... As i know whenever change in database like insert,update,delete SCN is
generated.
...

not true, whenever a transaction completes, the scn is "generated", SCN's are assigned to transactions as they complete, not during each "dml" operation.


And in your single user database, you are never alone, in Oracle - you are never alone. The background processes (smon in particular) are always doing work, they commit and hence the SCN increases.

the scn is related to transactions ending, and there are almost always transactions happening.

About SCN

Sathish Kumar, March 23, 2010 - 10:56 am UTC

Hi,Tom
As i know whenever change in database like insert,update,delete, SCN is generated.

But in my PC(Dedicated server) when i selected Current_scn from V$Database i found scn is going on changing every second without any insert or updates why?

How oracle differentiates committed and uncommitted data.
What is current_scn in V$database?

For Sathish

Aman...., March 24, 2010 - 5:26 am UTC

Sathish,

The SCN is not incrementing just like that. Since you are issuing a query for the view, oracle is incrementing the "query scn" . The SCN would also get generated at the time of the commit denoting the "commit time scn" which would essentially mark that the transaction is over.

The transaction status being committed or not is tracked from the transaction table that oracle maintains within each segment header where the undo image of the transaction is maintained. Also, the same is maintained within the block's Transaction Header as well where whether the transaction is active or not is marked.

You may want to read about the current_scn from here,
http://forums.oracle.com/forums/thread.jspa?messageID=3890738�

Hope that helps.

ABOUT SCN

Sathish Kumar, March 25, 2010 - 10:59 am UTC

Amman according to sam R.Alapati , changes to database like insert,update and delete generates SCN. I don't think querying a table(v$Database) will generate a scn, if so then how oracle Differentiates committed and uncommitted data.

I think as like ASM which has 2 definitions in oracle 10g
Automatic storage/segment Management. SCN means System Change/Commit Number.

Select current_scn from V$Database is System Change Number.
Select Commit_scn from Flashback_Transaction_Query is System Commit Number.
Tom Kyte
March 26, 2010 - 2:39 pm UTC

They do not. Please quote directly and give a reference, you might have misunderstood.

transactions ending - that moves the scn.


When you commit, your transaction is assigned an SCN, that is how we know your transaction committed. If you haven't committed, your transaction is not done, we know it is not done because the UNDO segment data would not be stamped "finished", because the REDO log would not have the commit record. That is how we know your transaction is not done.


In Oracle, ASM stands for Automatic Storage Management. ASSM stands for Automatic Segment Space Management - but I'm not sure what it has to do with anything, the SCN is done with or without ASM or ASSM.

For Sathish

Aman...., March 26, 2010 - 1:12 am UTC

Satish,

Did you even read the thread that I gave to you where Jonathan did explain why the number is increasing when you query the view?

Its basically because SCN is happening all the time, like a clock having time all the time.So even for a query, there would be a timestamp mapped and when you issue a select on the view, you are increasing the "query scn"! There are couple of variations in SCN if you dig it further. I believe that's not needed here but what is happening here is correct. So I would suggest again to read the thread link.

About the transaction committed/uncommitted, this information is maintained within the "Transaction Table" that's maintained within each Undo Segment. If a transaction was ever started, its entry would be there in it and also the status of it, whether it got finished or not successfully. So if a transaction is "over"(irrespective of whether its done through a commit or rollback) , querying transaction table would tell oracle about it.

I am not sure that why you are comparing ASMM and other things here.

HTH
Aman....

For Sathish

Aman...., March 26, 2010 - 1:26 am UTC

And just the pointer about the book, its not the case that only DMLs would "generate" the SCN. Its there all the time, every time.


insert append parent-child

pinguman, May 04, 2010 - 10:19 am UTC

Hi Tom

I have to purge some old data for two tables where one is parent and another is child.

What I do is insert to an empty table the data I want then truncate the original.

To get better performance I use INSERT APPEND to the empty table, after insert append we must run commit, this is where the possible problem arises.

To ensure child and parent data are consistent I must ensure that my insert session starst with same SCN, how can we ensure that? By using VERSIONS BETWEEN SCN minvalue and maxvalue?

Thank you



Tom Kyte
May 06, 2010 - 12:59 pm UTC

why not partition to purge????

or why not (since you are already copying out the data you want to keep) just copy, drop, rename???

to ensure that the data is CONSISTENT and current, you have to stop all other sessions from modifying this data using your current technique, you don't need to use SCN's, you have to PREVENT MODIFICATIONS (else anything modified whilst you were doing this operation would DISAPPEAR - so why bother doing it??!??!)

insert append parent-child

pinguman, May 10, 2010 - 2:04 pm UTC

Hi

We dont have partitioning, too expensive so we are using Standard Edition.

Copy, drop and rename is not a good idea for us because we need to data to be purged for some law reasons, so what we do is

copy data we want to be online from t1 to t_new
rename t1 to t_old
rename t_new to t1
export t_old
drop t_old
create indexes on t_new

I think this is oke but do you have better suggestions?

Thank you very much Tom
Tom Kyte
May 10, 2010 - 7:11 pm UTC

tell me again why copy/drop/rename isn't going to work for you?

you just DESCRIBED here doing a copy/drop/rename!!!

Bijoy Konwar, May 12, 2010 - 2:29 am UTC


SCN limit

Franky Wong, March 18, 2011 - 4:04 pm UTC

In response to http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:9434169398289#592633400346236629about if there is a limit on the SCN:

>> the scn is a 48 bit number
>> it is rather huge. even at 1,000 transactions per second - forever - it is unlikely to be encountered

Yes, there is a limit if the database has distributed transactions (i.e. if it communicates with others via db link)

1) A transaction could cause the SCN to increase by more than one (e.g. could be 10, or 100, or more).

2) In a distributed transaction, Oracle enforces a reasonableness test to the numerical value of SCN.

In a distributed transaction involving more than one databases, they will "sync up" the SCNs to the one with the highest value. In doing so, however, Oracle will check to see if the result is "reasonable", defined to be whether the result is less than a maximum/limit calculated to be the number of seconds since 1/1/1988 (assuming each month has 31 days) multipled by an internal reasonable SCN rate per second parameter (which is 16384).

We have seen databases, which for whatever reason, has a too high SCN - they will work fine if in isolation, but the moment they connect (or get connected) to others via db links (eg. select * from dual@dblink), ORA-600 [2252] errors would result, even causing the database to crash.

SCN

kumar, July 28, 2011 - 6:12 am UTC

Hi Tom,

does each transaction has 2 SCN ?

you mentioned in your book that COMMIT will generate and assign new SCN to a transaction -means Is it stored in UNDO- where is it stored for the transaction ?

Before Trnasaction starts -REDO also has SCN stored in it for the transaction - does it show the start of transaction?
Tom Kyte
July 28, 2011 - 7:26 pm UTC

redo has transaction information, we don't know the scn yet.

a transaction is assigned an scn when it commits - not before.

doro, August 19, 2011 - 11:09 am UTC

you said that "a block 'conceptually' has an SCN associated with it. In reality, there is transaction information in the block header that in conjunction with the rollback/undo segment information can be used to derive all of the necessary information. "

1)i don't know if i understand this quite well! can you please put some more details? what kind of information is stored in the header?

2) when is updated this info? after DBW writes some data in the datablock or after a CKPT?


Tom Kyte
August 30, 2011 - 1:07 pm UTC

1) a pointer to the undo segment where details on that transaction - whether it was committed, still going on, whatever - is held.

The undo segment associated with a given transaction "knows" about that transaction and what state that transaction is in.


2) nothing to do with dbwr or ckpt. It is information created and maintained by the transaction itself as the transaction progresses.

doro, August 19, 2011 - 12:21 pm UTC

sorry for this question in such a short time:
you said "When you commit, your transaction is assigned an SCN"

but if i use the log miner to see what is inside the log of an uncommited transaction i can see the field SCN has a number assigned already, but the CSCN (SCN when the transaction commited) and timestamps fields are NULL!The only thing that happens at a commit is that oracle adds the SCN value(the SCN at which the transaction started) in the field CSCN , and also adds a timestamp! now all the statemens are commited! usually a begginer like me and a non english native speaker can easily be confused, maybe like i'm right now! so when that SCN was assigned at the start of the transaction it was already there moved by some other commited transaction, before i commit my transactions some others will move the SCN to higher values, when i will commit my transaction i will actualy move the SCN further with the last SCN in the system?
Tom Kyte
August 30, 2011 - 1:10 pm UTC

it adds the scn assigned to the transaction at commit time - not the scn from the start of the transaction.


the scn isn't assigned to a transaction until it commits - it is a commit time ordering.


The scn is just a clock, every time you commit (or rollback) it increments - it ticks forward. The scns you are looking at are just like timestamps - they measure time in "oracle time" not clock time.


Is this article true?

A reader, January 18, 2012 - 2:23 pm UTC

I got this article forwarded about some flaw in Oracle database. I haven't seen anything yet about a flaw in the fundamental design of the Oracle database architecture. They talk about the SCN and say that's the core issue.

http://www.infoworld.com/d/security/fundamental-oracle-flaw-revealed-184163-0

Your comments please.

Thanks,


Tom Kyte
January 18, 2012 - 2:59 pm UTC

read the article, it references filed bugs.

Is it a fundamental flaw? I don't believe so, the conditions to encounter it are pretty rare, extremely rare. To call it a security flaw is not something I necessarily agree with. A pretty bad bug if you hit the rarest of conditions - yes.

there is a fix for it, prior to releasing the article there was a fix for it.

follow up,

A reader, January 19, 2012 - 8:44 am UTC

Thanks for following up. My surprise is how is this detected so late when Oracle is been in the market for decades. We are already thinking to find out the latest SCN value of thousands of database just in case.

thanks,

Tom Kyte
January 19, 2012 - 12:34 pm UTC

see

My Oracle Support Note 1376995.1

and Eric Maurice's Blog - http://blogs.oracle.com/security/entry/learning_more_about_oracle_database

scn

Sajid, February 13, 2012 - 2:00 am UTC

Hi Tom

1.for each and every transaction oracle define a unique id called scn.wether it is committed or not committed

then how oracle identifies which transaction is commited and which is not


Tom Kyte
February 13, 2012 - 8:15 am UTC

That is not correct, the SCN is assigned to a transaction at commit time. It is a commit time ordering feature.


We can tell if a transaction (whose transaction ID points to an undo segment) is committed or not by looking at the undo header information. The transaction id tells us where to look in the rollback/undo segment to find the state of the given transaction.

Ming, March 22, 2012 - 9:51 am UTC

Hi Tom,
You stated in the above context the SCN in data block is a "commit" scn, ordered by "commit-time". Is it correct this scn is only referred to the scn in ITL entry? There is other scn in block header -- is it a "last" block changed scn (not neccessarily committed)? During database Recovery, is it the block header scn being used when comparing the scn of that block in redo record?
Many thanks.
Tom Kyte
March 22, 2012 - 10:37 am UTC

The SCN is technically not on the block, the transaction information in the block header it use to figure out what the SCN is.

during recovery, we use information about the datafile to see how much redo we need to apply - it would be more checkpoint related than block by block.

Ming, March 22, 2012 - 11:59 am UTC

Thanks Tom for the help!
Can you please further clarify "The SCN is technically not on the block, the transaction information in the block header it use to figure out what the SCN" -- what is the purpose for Oracle to figure out from that SCN? CR fabrication uses the SCN in ITL entry specific for that row right? What is the SCN in block header used for?

In your statement, "during recovery, we use information about the datafile to see how much redo we need to apply", can I say you mean for the SCN information in "datafile header block" -- I guess someone called it a "(recovery) start-scn" updated during checkpoint? During recovery in its "second pass" scanning the resulting redo list, Oracle should compare the block change SCN in the redo with some SCN in the data block to determine if it encounters a "stuck recovery"? which SCN in data block does Oracle use in this (second pass) recovery phase?
Tom Kyte
March 22, 2012 - 4:57 pm UTC

the scn is not on the block i said. So there is no scn "IN" the block header.

In recovery, we look at the datafile to see what the last checkpoint was (being very broad here). That tells us where to start in the redo stream to recover that file - we read all of the redo from that point in the logs on and apply it (if necessary) to the blocks it directs us to.