Oracle
 sql >> Base de données >  >> RDS >> Oracle

LAST_NUMBER sur la séquence oracle

C'est normal, oui. À partir de la documentation pour les all_sequences vue du dictionnaire de données , last_number est :

Cela peut être recréé avec une nouvelle séquence :

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 

Le last_number sauté par la taille du cache, ce qui est normal.

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 

Le last_number descend, mais reflète maintenant le dernier numéro de séquence réel généré. Le DDL a (apparemment) provoqué la mise à jour des données écrites sur le disque pour refléter ce qui se trouve être la valeur actuelle, plutôt que le haut du cache - soit l'ancien cache à 20 valeurs, soit le nouveau cache à 5000 valeurs. Dans votre cas, vous avez 2222292447 , ce qui signifie simplement que vous étiez dix valeurs plus loin dans le cache que moi lorsque j'ai exécuté le alter .

La valeur enregistrée sur le disque est en grande partie là, de sorte que si la base de données tombe en panne, elle sait d'où la récupérer. Au redémarrage, la séquence commencera à générer des nombres à partir du last_number enregistré . Pendant le fonctionnement normal, il n'a pas besoin de s'y référer, il met simplement à jour la valeur sur le disque lorsque de nouvelles valeurs sont mises en cache. Cela empêche les numéros de séquence d'être réémis après un crash, sans avoir besoin de faire un verrouillage coûteux (lent) pour maintenir la valeur en temps réel - ce que le cache est là pour éviter, après tout.

Il n'y aurait un problème que si la last_value était inférieur à une séquence générée réelle, mais cela ne peut pas arriver. (Eh bien, à moins que la séquence ne soit définie sur cycle).

SQL> select SEQ_PAGE_ID.nextval from dual;

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

Le prochain numéro de séquence généré succède au dernier avant le changement de taille du cache ; il n'a pas réutilisé une ancienne valeur comme vous auriez pu vous inquiéter de la valeur du dictionnaire.

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 

Le last_number affiche maintenant la valeur stockée précédente incrémentée de la taille du cache de 5000. Ce qui se trouve dans le dictionnaire de données ne changera plus jusqu'à ce que nous ayons consommé les 5000 valeurs du cache, ou que quelque chose se passe ailleurs qui l'affecte - la base de données étant rebondie , la séquence étant à nouveau modifiée, etc.