sql >> Databasteknik >  >> RDS >> Oracle

LAST_NUMBER på orakelsekvens

Det här är normalt, ja. Från dokumentationen för all_sequences dataordbokvy , last_number är:

Detta kan återskapas med en ny sekvens:

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 

last_number hoppade upp med cachestorleken, vilket är normalt.

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 

last_number går ner, men återspeglar nu det faktiska senast genererade sekvensnumret. DDL har (uppenbarligen) orsakat att data som skrivits till disken har uppdaterats för att återspegla vad som råkar vara det aktuella värdet, snarare än toppen av cachen - antingen den gamla cachen med 20 värden eller den nya cachen med 5000 värden. I ditt fall fick du 2222292447 , vilket bara betyder att du var tio värden längre i cachen än vad jag var när jag körde alter .

Värdet som sparas på disk finns till stor del så att om databasen kraschar vet den var den ska hämta. Vid omstart kommer sekvensen att börja generera nummer från det inspelade last_number . Under normal körning behöver den inte hänvisa tillbaka till det, den uppdaterar bara värdet på disken när nya värden cachelagras. Detta förhindrar att sekvensnummer återutges efter en krasch, utan att behöva göra dyr (långsam) låsning för att bibehålla värdet i realtid - vilket är vad cachen är där för att undvika, trots allt.

Det skulle bara vara ett problem om last_value var lägre än en faktiskt genererad sekvens, men det kan inte hända. (Tja, om inte sekvensen är inställd på cykling).

SQL> select SEQ_PAGE_ID.nextval from dual;

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

Nästa sekvensnummer som genereras följer på det sista innan cachestorleksändringen; det har inte återanvänt ett gammalt värde som du kanske har varit orolig för från ordboksvärdet.

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 

last_number visar nu det tidigare lagrade värdet ökat med cachestorleken på 5000. Det som finns i dataordboken nu kommer inte att ändras igen förrän vi har förbrukat alla 5000 värden från cachen, eller något händer någon annanstans som påverkar den - databasen studsar , sekvensen ändras igen, etc.



  1. MySQL-fel #2014 - Kommandon osynkroniserade; du kan inte köra det här kommandot nu

  2. Fel vid användning av oracle.dataaccess.dll

  3. Skapa en databas med MySQL Workbench från befintligt schema/modell

  4. Begränsa resultat från sammanfogade tabeller till en rad