2014-05-13 11 views
7

Ho un SEQ_PAGE_ID sequenzalast_number sequenza di Oracle

SEQUENCE_NAME INCREMENT_BY CACHE_SIZE LAST_NUMBER    
------------------------------------------------------- 
SEQ_PAGE_ID  1    20   2222292456 

Per cambiare il CACHE_SIZE, ho usato qui di seguito lo script,

alter sequence SEQ_PAGE_ID CACHE 5000;

Quando ho controllato la query,

select ... from user_sequences where sequence_name = 'SEQ_PAGE_ID'; 


SEQUENCE_NAME INCREMENT_BY CACHE_SIZE LAST_NUMBER    
------------------------------------------------------- 
SEQ_PAGE_ID  1    5000   2222292447 

Il LAST_NUMBER è stato modificato da 2222292456 a 2222292447. E 'successo a causa dell'alterazione della sceneggiatura?

risposta

11

Questo è normale, sì. Da documentation for the all_sequences data dictionary view, last_number è:

Ultimo numero di sequenza scritto su disco. Se una sequenza utilizza la memorizzazione nella cache, il numero scritto sul disco è l'ultimo numero inserito nella cache della sequenza. È probabile che questo numero sia maggiore dell'ultimo numero di sequenza che è stato utilizzato.

Questo può essere ricreato con una sequenza fresca:

SQL> create sequence SEQ_PAGE_ID start with 2222292436 increment by 1 cache 20; 

sequence SEQ_PAGE_ID created. 

SQL> select sequence_name, increment_by, cache_size, last_number 
    2 from user_sequences where sequence_name = 'SEQ_PAGE_ID'; 

SEQUENCE_NAME     INCREMENT_BY CACHE_SIZE LAST_NUMBER 
------------------------------ ------------ ---------- ----------- 
SEQ_PAGE_ID        1   20 2222292436 

SQL> select SEQ_PAGE_ID.nextval from dual; 

    NEXTVAL 
---------- 
2222292436 

SQL> select sequence_name, increment_by, cache_size, last_number 
    2 from user_sequences where sequence_name = 'SEQ_PAGE_ID'; 

SEQUENCE_NAME     INCREMENT_BY CACHE_SIZE LAST_NUMBER 
------------------------------ ------------ ---------- ----------- 
SEQ_PAGE_ID        1   20 2222292456 

Il last_number saltato dalla dimensione della cache, che è normale.

SQL> alter sequence SEQ_PAGE_ID CACHE 5000; 

sequence SEQ_PAGE_ID altered. 

SQL> select sequence_name, increment_by, cache_size, last_number 
    2 from user_sequences where sequence_name = 'SEQ_PAGE_ID'; 

SEQUENCE_NAME     INCREMENT_BY CACHE_SIZE LAST_NUMBER 
------------------------------ ------------ ---------- ----------- 
SEQ_PAGE_ID        1  5000 2222292437 

Il last_number scende, ma ora riflette il numero effettivo ultima sequenza generata. Il DDL ha (apparentemente) causato l'aggiornamento dei dati scritti sul disco per riflettere ciò che è il valore corrente, piuttosto che la parte superiore della cache: la vecchia cache da 20 valori o la nuova cache da 5000 valori. Nel tuo caso hai 2222292447, il che vuol dire che avevi dieci valori oltre la cache rispetto a quando avevo eseguito lo alter.

Il valore salvato su disco è in gran parte presente in modo tale che se il database si arresta in modo anomalo sa da dove prelevare. Al riavvio la sequenza inizierà a generare numeri dal last_number registrato. Durante il normale funzionamento non ha bisogno di fare riferimento a questo, ma aggiorna il valore sul disco quando i nuovi valori vengono memorizzati nella cache. Questo evita che i numeri di sequenza vengano riemessi dopo un crash, senza dover effettuare costosi (lenti) blocchi per mantenere il valore in tempo reale - che è ciò che la cache è lì per evitare, dopo tutto.

Ci sarebbe solo un problema se il last_value fosse inferiore a una sequenza generata, ma ciò non può accadere. (Bene, a meno che la sequenza non sia impostata per il ciclo).

SQL> select SEQ_PAGE_ID.nextval from dual; 

    NEXTVAL 
---------- 
2222292437 

Il numero di sequenza successivo generato segue dall'ultimo prima della modifica della dimensione della cache; non ha riutilizzato un vecchio valore come si sarebbe potuto essere preoccupato dal valore del dizionario.

SQL> select sequence_name, increment_by, cache_size, last_number 
    2 from user_sequences where sequence_name = 'SEQ_PAGE_ID'; 

SEQUENCE_NAME     INCREMENT_BY CACHE_SIZE LAST_NUMBER 
------------------------------ ------------ ---------- ----------- 
SEQ_PAGE_ID        1  5000 2222297437 

Il last_number ora mostra il valore memorizzato precedente incrementato della dimensione della cache del 5000. Qual è nel dizionario dei dati ora non cambierà di nuovo finché non avremo consumato tutti i 5000 valori costituiscono la cache, o qualcosa del genere accade altrove che lo influenza - il database viene rimbalzato, la sequenza viene modificata di nuovo, ecc.

6

Quando la sequenza è in cache, last_number rappresenta il numero di keep di oracle. In caso contrario, rappresenta l'ultima sequenza utilizzata da Oracle. Con il comando ALTER, si modificano le impostazioni della sequenza, in modo da Oracle a filo è "cache sequenza"

Ecco un semplice esempio

SQL> drop sequence test; 
Sequence dropped 

SQL> create sequence test cache 20; 
Sequence created 

SQL> select last_number from user_sequences where sequence_name='TEST'; 
LAST_NUMBER 
----------- 
      1 

SQL> select test.nextval from dual; 
    NEXTVAL 
---------- 
     1 

SQL> select last_number from user_sequences where sequence_name='TEST'; 
LAST_NUMBER 
----------- 
     21 

SQL> alter sequence test CACHE 5000; 
Sequence altered 

SQL> select last_number from user_sequences where sequence_name='TEST'; 
LAST_NUMBER 
----------- 
      2 

SQL> select test.nextval from dual; 
    NEXTVAL 
---------- 
     2 

SQL> select last_number from user_sequences where sequence_name='TEST'; 
LAST_NUMBER 
----------- 
     5002 

SQL> 
Problemi correlati