Sequence.nextval can really deceive you !!
Yes, they really can.
Yesterday, I noticed that one of the sequence number (pol_no_seq) in our IH application was giving different set of results when accessed (pol_no_seq.nextval) from two different machines. When I shared this observation with colleagues, the feedback was something like "It does not make sense" and frankly speaking, even I thought the same :-) But, how could I ignore what I actually saw with my own eyes ? I was really puzzled.
Given below is the explanation of what and why it happenned, based on my findings from some forums:
Definition of pol_no_seq :
CREATED 25-JAN-07
LAST_DDL_TIME 25-JAN-07
SEQUENCE_OWNER INSURANCE
SEQUENCE_NAME POL_NO_SEQ
MIN_VALUE 1
MAX_VALUE 1000000000000000000000000000
INCREMENT_BY 1
CYCLE_FLAG N
ORDER_FLAG N
CACHE_SIZE 200
LAST_NUMBER 2802765
Results :
Machine A : pol_no_seq.nextval->28000146
Machine A : pol_no_seq.nextval->28000147
Machine B : pol_no_seq.nextval->28000412
Machine B : pol_no_seq.nextval->28000413
Machine A : pol_no_seq.nextval->28000148
Machine B : pol_no_seq.nextval->28000414
Why it happened?
This could happen in a Oracle RAC environment.
Oracle RAC allows multiple computers to run Oracle RDBMS software simultaneously while accessing a single database, thus providing a clustered database.In an Oracle RAC environment, two or more computers (each with an instance) concurrently access a single database. This allows an application or user to connect to either computer and have access to a single coordinated set of data.
Now coming back to our problem - Sequence being "noordered", oracle will not guaranteee the order in which numbers are generated. The sequence cache is in the shared pool, therefore sessions on the same node can share the cached entry, but sessions on different nodes cannot. I wonder why Oracle doesn't make "ordered” the default for sequences ??
If we make the sequence "ordered" and increase the cache size to say, 1000; selecting the nextval from either of nodes will get the next number as expected. But, at the same time, there would be some performance implications due to cluster synchronization.
How does RAC synchronize sequences?
In Oracle 10g RAC, if you specify the “ordered” clause for a sequence, then a global lock is allocated by the node when you access the sequence.
This lock acquisition happens only at the first sequence access for the node (A), and subsequent uses of the sequence do not wait on this lock. If another node (B) selects from that sequence, it requests the same global lock and once acquired it returns the sequence's next value.
The wait event associated with this activity is recorded as “events in waitclass Other” when looked in gv$system_event. So much for event groups, it couldn't be more obscure. That view shows overall statistics for the session.
However if you look in the gv$session_wait_history it shows as “DFS lock handle” with the “p1" parameter been the object_id of the sequence. This second view has a sample of the last 10 wait events for a session.
In a SQL_TRACE with waitevents (10046 trace) it will be a “DFS lock handle” but in AWR or statspack reports it will be “events in waitclass Other”. So much for consistency.
Two ways for determining whether your database is running in RAC environment or not :
1. BEGIN
IF dbms_utility.is_cluster_database THEN
dbms_output.put_line('Running in SHARED/RAC mode.');
ELSE
dbms_output.put_line('Running in EXCLUSIVE mode.');
END IF;
END;
/
2. show parameter CLUSTER_DATABASE - If the value of CLUSTER_DATABASE is FALSE then database is not running in RAC Mode else it is.
That is all for today. Feel free to provide feedback.........Thanks.
[I published this content on my official blog on 8/12/2010 11:46 PM]
Yesterday, I noticed that one of the sequence number (pol_no_seq) in our IH application was giving different set of results when accessed (pol_no_seq.nextval) from two different machines. When I shared this observation with colleagues, the feedback was something like "It does not make sense" and frankly speaking, even I thought the same :-) But, how could I ignore what I actually saw with my own eyes ? I was really puzzled.
Given below is the explanation of what and why it happenned, based on my findings from some forums:
Definition of pol_no_seq :
CREATED 25-JAN-07
LAST_DDL_TIME 25-JAN-07
SEQUENCE_OWNER INSURANCE
SEQUENCE_NAME POL_NO_SEQ
MIN_VALUE 1
MAX_VALUE 1000000000000000000000000000
INCREMENT_BY 1
CYCLE_FLAG N
ORDER_FLAG N
CACHE_SIZE 200
LAST_NUMBER 2802765
Results :
Machine A : pol_no_seq.nextval->28000146
Machine A : pol_no_seq.nextval->28000147
Machine B : pol_no_seq.nextval->28000412
Machine B : pol_no_seq.nextval->28000413
Machine A : pol_no_seq.nextval->28000148
Machine B : pol_no_seq.nextval->28000414
Why it happened?
This could happen in a Oracle RAC environment.
Oracle RAC allows multiple computers to run Oracle RDBMS software simultaneously while accessing a single database, thus providing a clustered database.In an Oracle RAC environment, two or more computers (each with an instance) concurrently access a single database. This allows an application or user to connect to either computer and have access to a single coordinated set of data.
Now coming back to our problem - Sequence being "noordered", oracle will not guaranteee the order in which numbers are generated. The sequence cache is in the shared pool, therefore sessions on the same node can share the cached entry, but sessions on different nodes cannot. I wonder why Oracle doesn't make "ordered” the default for sequences ??
If we make the sequence "ordered" and increase the cache size to say, 1000; selecting the nextval from either of nodes will get the next number as expected. But, at the same time, there would be some performance implications due to cluster synchronization.
How does RAC synchronize sequences?
In Oracle 10g RAC, if you specify the “ordered” clause for a sequence, then a global lock is allocated by the node when you access the sequence.
This lock acquisition happens only at the first sequence access for the node (A), and subsequent uses of the sequence do not wait on this lock. If another node (B) selects from that sequence, it requests the same global lock and once acquired it returns the sequence's next value.
The wait event associated with this activity is recorded as “events in waitclass Other” when looked in gv$system_event. So much for event groups, it couldn't be more obscure. That view shows overall statistics for the session.
However if you look in the gv$session_wait_history it shows as “DFS lock handle” with the “p1" parameter been the object_id of the sequence. This second view has a sample of the last 10 wait events for a session.
In a SQL_TRACE with waitevents (10046 trace) it will be a “DFS lock handle” but in AWR or statspack reports it will be “events in waitclass Other”. So much for consistency.
Two ways for determining whether your database is running in RAC environment or not :
1. BEGIN
IF dbms_utility.is_cluster_database THEN
dbms_output.put_line('Running in SHARED/RAC mode.');
ELSE
dbms_output.put_line('Running in EXCLUSIVE mode.');
END IF;
END;
/
2. show parameter CLUSTER_DATABASE - If the value of CLUSTER_DATABASE is FALSE then database is not running in RAC Mode else it is.
That is all for today. Feel free to provide feedback.........Thanks.
[I published this content on my official blog on 8/12/2010 11:46 PM]
Comments
Post a Comment