Skip to Main Content

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question.

Asked: January 18, 2017 - 10:21 pm UTC

Last updated: January 20, 2017 - 12:11 pm UTC

Version: 12c

Viewed 1000+ times

You Asked

Hi,
I'd like to ask about a sequence reset problem on RAC.

The common solution is to do:
1) get curr value
2) set increment to -curr value
3) call nextval to go to 0
4) revert increment back to one
(btw between steps 1 and 2, 2 and 3 etc. some other session can call nextval which can cause various problems... so it's not really a reliable solution)

We're facing an issue where something happened on one of the nodes and the sequence got stuck in the negative increment of step 2 or 3 and now we're getting "sequence goes below MINVALUE and cannot be instantiated" when the proc is called again or when the seq is to be used.
The reset proc code was not expecting this situation and cannot recover.

The question is this:
You have two nodes with cached seq ids like this: node 1:1-100, node 2:101-200.
You call nextval from node 1. You can get say 10, but from node 2 you can get 120.
Now, if you call the reset proc from node 1, what will you get as a result of step 3 ? Is it 0 (10-10) or 110 (120-10) ?
Will node 1 reset it to 0 even though the curr val on node 2 is 120 ?
Basically, do you have to be aware of the highest taken curr val across all nodes to correctly set the negative increment ?

It would be very welcome if there was a simple built-in properly functioning reset function...

Thx
Petr

and Connor said...

"It would be very welcome if there was a simple built-in properly functioning reset function..."

I agree...but dont forget what the motivation for sequences is - a scalable solution "from which multiple users can generate unique integers" (quoted text from the Concepts guide).

So the idea of "resetting" them, ie, instilling some inherent business definition in the resulting integers, eg "This year we restart from 1" is a departure from their intended purpose, hence the problem you're seeing.

Option 1- using decrement

Even if you *know* exactly what number to decrement by, you will *always* run the risk of encountering 'ORA-08004: sequence SEQ.NEXTVAL' if the sequence is in use during this reset task. For example, lets say I'm doing:

insert into t values (seq.nextval);

then even doing "lock table t in exclusive mode" before your maintenance does not solve the issue, because the moment I do: 'alter sequence' I will release that lock.

In order to keep occurrences of that down to a minimum, you could look at doing:

alter sequence seq nocache

temporary during the reset, so your nextval check will not be as far "out of date" with respect to other instances.

Option 2- using cycle

You could approach this from a different tack. Find the current sequence value, and then issue:

alter sequence seq cycle minvalue 1 maxvalue [current max]

The next seq.nextval will cause the sequence to cycle, and then you issue:

alter sequence seq cycle minvalue 1 maxvalue [very high number]



Rating

  (2 ratings)

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

Comments

Need answer for the situation on RAC

A reader, January 19, 2017 - 8:35 am UTC

Thx for your response, yes we understand. This is a situation in a customer environment where we can't change code or test anything right now, hence these questions.

To explain the situation further - we use the reset because the seqs are used in Truncate/Reload ETLs run daily so that the numbers don't grow indefinitely.
For the seq in question we see that the increment is stuck at -9mil even though the table only loads 3 mil rows.
So we think the increment is set incorrectly in the proc because of the different curr values on different nodes.
This problem occurred after long successful production time, after something (crash, hang) happened in one of the nodes.

We mainly need an answer to these questions below.

MAIN QUESTIONS:
On RAC, you have two nodes with cached seq ids like this: node 1:1-100, node 2:101-200.
You call nextval from node 1. You can get say 10, but from node 2 you can get 120.
Now, if you call the reset proc from node 1, what will you get as a result of step 3 ? Is it 0 (10-10) or 110 (120-10) ?
Will node 1 reset it to 0 even though the curr val on node 2 is 120 ?
Basically, do you have to be aware of the highest taken curr val across all nodes to correctly set the negative increment ?
How can you even find out about the seq status from one node on a different node ?

Connor McDonald
January 20, 2017 - 12:11 pm UTC

"Basically, do you have to be aware of the highest taken curr val across all nodes to correctly set the negative increment ? "

My point is this - you *always* run the risk of getting a negative, whether its RAC or single instance. The issue is if the sequence is in use when you do the reset. If it is - then the risk is there. All you can do *reduce* the risk, not eliminate it.


Indirection

lh, January 19, 2017 - 8:50 am UTC

Hi

One way to reset sequences is to use synonym which is actually pointing to sequence. And then You change the synonym to point to another sequence.




Connor McDonald
January 20, 2017 - 12:11 pm UTC

True - but you do run the risk of invalidations