UNDO Data
-- Versione Oracle 11g
Nelle operazioni di flashback query, flashback transaction e table o Recovery from failed transaction sono fondamentali gli Undo data.
Gli Undo Data sono copie di dati sottoposti ad una transazione e sono mantenuti finché la transazione non termina con una commit, rollback, ddl o una sessione terminata "abnormally" o con il comando shutdown abort. Quindi il tablespace Undo è come un tablespace temporaneo.
I dati di undo sopravvivono alla chiusura del database.
N.B. Undo segment sono classici segment quindi composti da extent e blocchi.
Nelle operazioni di flashback query, flashback transaction e table o Recovery from failed transaction sono fondamentali gli Undo data.
Gli Undo Data sono copie di dati sottoposti ad una transazione e sono mantenuti finché la transazione non termina con una commit, rollback, ddl o una sessione terminata "abnormally" o con il comando shutdown abort. Quindi il tablespace Undo è come un tablespace temporaneo.
I dati di undo sopravvivono alla chiusura del database.
Ogni transazione è assegnata ad un solo Undo Segment ma un Undo Segment può service più transazioni contemporaneamente.
Ogni volta che c'è una richiesta di update, il server process (vedi post Listener: connessione - sessione) copia alcuni blocchi di undo datafile nel Database Buffer Cache, e salva qui il valore dei dati prima della modifica.
Finché non viene eseguita la commit i vecchi dati sono sempre visibili da una secondo utente che esegue la stessa query: è in questo che consiste la READ CONSISTENCY.
Ogni volta che c'è una richiesta di update, il server process (vedi post Listener: connessione - sessione) copia alcuni blocchi di undo datafile nel Database Buffer Cache, e salva qui il valore dei dati prima della modifica.
Finché non viene eseguita la commit i vecchi dati sono sempre visibili da una secondo utente che esegue la stessa query: è in questo che consiste la READ CONSISTENCY.
Inoltre è possibile effettuare il rollback dei dati.
E' possibile vedere a quale undo segment è associata una transazione interrogando la vista dinamica V$TRANSACTION.
Esempio di READ CONSISTENCY
SQL> show parameter undo;
UNDO_MANAGEMENT='AUTO'
UNDO_TABLESPACE='UNDOTBS1'
UNDO_RETENTION=900 (tempo in secondi)
oppure
SQL> select * from v$parameter where name like '%undo%';
SQL> show parameter undo_tablespace
NAME TYPE VALUE
-----------------------------------------
undo_tablespace string UNDOTBS1
La sessione 79 ha creato 2 record all'interno dell'area UNDO contenuti in un solo bloco di undo.
Ad esempio il primo utente che esegue la update sulla tabella T legge il valore "Jacob". Se non ha ancora eseguito il comando commit, il secondo utente che effettua una select sulla stessa tabella T legge ancora il valore "Frank".
Questo avviene perché il Server Process#1 aggiorna un campo dell'header del blocco (presente nel database buffer cache), chiamato Transaction Slot, che contiene i dettagli della transazione in corso con gli estremi di chi ha fatto la modifica e le informazioni relative al blocco undo contenente il vecchio valore. Quindi il Server Process#2 con la select, legge il TS e viene indirizzato sul blocco undo che contiene il vecchio valore "Frank".
Di default i parametri di inizializzazione del database sono impostati come segue:
SQL> show parameter undo;
UNDO_MANAGEMENT='AUTO'
UNDO_TABLESPACE='UNDOTBS1'
UNDO_RETENTION=900 (tempo in secondi)
oppure
SQL> select * from v$parameter where name like '%undo%';
NAME TYPE VALUE
-----------------------------------------
undo_tablespace string UNDOTBS1
UNDO_MANGEMENT= 'AUTO'
noto come AUM è abilitato di default nella versione oralce 11g mentre in quelle precedenti è null. Quindi in fase di migrazione del db da un versione precedente fare attenzione a questo parametro. L'impostazione AUTO significa che in automatico viene gestito la dimensione del tablespace UNDOTBS1 e quindi è di tipo autoextend con maxsize unlimited (in realtà si estende fino a 32GB).
Questa impostanzione implica che il db da solo aggiusta il parametro di undo_retention in base al più lungo tempo di esecuzione di una Flashback Operation o delle query o dml attive perchè deve garantire la read consistency
UNDO RETENTION= 900
esprime per quanto tempo in secondi sono conservate i vecchi valori al termine di una transazione e può essere cambiata con il comando seguente:
SQL> ALTER SYSTEM SET undo_retention=1440 scope=both;
In generale il valore di Undo Retention è impostato ugale al più lungo tempo di esecuzione di una Flashback Operation o delle query o dml attive.
I dati di undo hanno tre stati o categorie:
uncommitted --> active undo e serve per il rollback di una transazione. Per questo non possono mai essere sovrascritti perchè contiene dati non commitati che potrebbero essere rollbackati.
unexpired --> sono gli undo data committati. Quando si effettua la commit gli undo data passano allo stato unexpired e quindi non possono essere utilizzati per il tempo di retention perchè servono per "read consistency" e Oracle Flashback operations.
expired --> Trascorso il tempo di retention, gli undo data passano allo stato expired e quindi possono nuovamente essere utilizzati o sovrascritti. Per questo motivo si dice che gli undo segment sono circolari.
Se arriva una nuova transazione e lo spazio del tablespace undo è pieno e non ci sono undo data in stato expired, AUM cerca di estendere il tablespace Undo ma se questo non è autoextend o non si è impostato maxsize unlimited allora sovrascrive gli undo unexpired piuttosto che bloccare la transazione.
Se si vuole invece conservare gli undo data expired (e quindi appartenenti a transazioni committate e quindi vecchi valori) anche a scapito del fallimento di transazioni (perché non c'è più spazio nel tablespace e i data sono in stato unexiperd, come detto prima), occorre abilitare l'attributo RETENTION GUARANTEE del tablespace Undo.
SQL> ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;
Questa opzione mi garantisce di conservare il vecchio valore dei dati per tutto il tempo di rentention anche se si dovessero presentare nuove transazioni e non c'è spazio sul tablespace di undo e non ci sono undo data da sovrascrivere.
SQL> ALTER TABLESPACE undotbs1 RETENTION NOGUARANTEE;
Se non c'è sufficiente spazio nel tablespace undo compare il messaggio
ORA 01555 - Snapshot too old.
La dimensione UNDO può essere controllata con il parametro undo_retention e la dimensione del tablespace UNDO e le impostazioni per questi sono determinate dal livello di attività delle DML nel database.
La colonna TUNED_UNDORETENTION della vista V$UNDOSTAT indica per quanto tempo è conservato un undo nel tablespace di riferimento.
La vista V$transaction individua a quali undo segments è associata una transazione.
E s e m p i o
Supponiamo di avere una tabelle così fatta
SQL> select * from PDBTSADM.dept;
DEPTNO DEPT_NAME
---------- -----------------------------------
1 IT Dept
2 FINANCE
SQL> update PDBTSADM.dept set dept_name='XXX';
Query che individua le righe presenti nel tablespace undo.
SQL> select a.sid, a.serial#, a.username, b.used_urec, b.used_ublk
from v$session a, v$transaction b
where a.saddr=b.ses_addr;
SID SERIAL# USERNAME USED_UREC USED_UBLK
-----------------------------------------------------
79 7253 PDBTSADM 2 1
USED_UREC = numero di undo record occupati dalla transazione
USED_BLOCK = numero di undo block occupati dalla transazione
Quindi nell'undo tablespace ho un blocco contenente due righe modificate.
A seguito del commit o del rollback la query di prima non resituisce record perchè sono liberati gli undo block all'interno del undo segment.