È possibile evitare questo errore assegnando i segmenti
di rollback e configurando i parametri adeguati.
Prima di esaminare a fondo questo problema, sarà necessario
spiegare prima di tutto cosa sono i segmenti di rollback. I segmenti
di rollback sono coinvolti in ogni transazione che si presenta
all'interno d'una base dati. Poiché gestiscono la capacità
della base di dati di maneggiare le transazioni, svolgono un ruolo
chiave nel buon funzionamento della base dati stessa.
I segmenti di rollback catturano l' immagine dei dati
come erano prima dell' inizio della transazione infatti le query
effettuate durante una transazione restituiranno i dati catturati
dal rollback. Il numero e la grandezza dei segmenti di rollback
sono specificati dal DBA durante la creazione della base dati.
Le informazioni sulle condizione dei segmenti di rollback sono
contenuti nella vista DBA_ROLLBACK_SEGS.
Un segmento di rollback consiste in una serie di blocchi attigui
chiamati extents. In una base
dati ideale, ogni transazione dovrebbe essere eseguita all'interno
di una singola extent. Tuttavia, ciò accade raramente.
Quando una transazione non ha più spazio sufficiente per
essere eseguita allinterno di un extent, il segmento di
rollback cerca un altro extent in cui poter continuare a scrivere.
Il segmento usa l extents in maniera ordinata e circolare,
spostandosi da un extent allaltro in maniera sequenziale
dopo che l extent precedente è stato pienamente occupato
come si trattasse di un record. La parte iniziale del record è
la head del segmento di rollback.
La coda è il tail.
È tuttavia importante assicurarsi che i diversi segmenti
di rollback siano abbastanza grandi per maneggiare il loro carico
di transazione.
La documentazione ORACLE suggerisce alcune regole utili a riguardo
dei segmenti di rollback:
Una transazione può usare soltanto un segmento di rollback
per memorizzare tutto il relativo record.
Le transazioni multiple possono scrivere nello stesso extent.
La head del segmento di rollback non entra mai in un extet di
rollback attualmente occupato dal tail.
Se la head non può usare lextent seguente, assegna
un altro lextent e lo inserisce nel blocco
Da questi principi si può dedurre che il tempo di transazione
così come il formato della transazione è importante.
Per esempio, una transazione che modifica soltanto un byte ma
necessita di un periodo di tempo abbastanza lungo prima che venga
terminato potrebbe indurre un segmento di rollback a crescere
senza che sia effettivamente necessario.
La grandezza necessaria per un segmento di rollback dipende direttamente
dalle transazioni che avvengono nella base dati, se queste sono
rare o frequenti.
Il numero dei segmenti di rollback sono necessari per impedire
il conflitto fra i processi e può essere determinato con
l' uso della vista di V$WAITSTAT. I wait di tale vista
sono indicativi del conflitto. La seguente query di V$WAITSTAT
visualizza il numero di wait dallinizio dellistanza.
SELECT Class, Count
FROM V$WAITSTAT
WHERE Class LIKE '%undo%';
Qualsiasi valore diverso da zero nella colonna count indica lesistenza
di un conflitto nell intestazione del segmento di rollback.
Per sapere la grandezza ed il numero di rollback segments necessari
alla base dati, è sufficiente effettuare un test. È
possibile cominciare con i piccoli segmenti di rollback e fare
in modo che lapplicazione li forzi ad estendersi. Il formato
massimo che tutto il segmento di rollback raggiunge durante il
test è il formato necessario da utilizzare. Se il più
grande formato richiede meno di 10 extent, o più di 30,
sarebbe necessario abbassare o aumentare la grandezza dellextent
e ripete il test. Per le grandi transazioni è possibile
creare i segmenti separati di rollback.
Per settare la grandezza dell extent del rollback segment
è raccomandabile utilizzare lo stesso valore per ogni extent
ed assegnare al rollback segment una grandezza pari a un multiplo
della grandezza dellextent.
I segmenti di rollback assegnano dinamicamente lo spazio una
volta richiesti e cancellano l'assegnazione dello spazio quando
non sono più necessari (se utilizzati gli adeguati paramentri).
Quanti meno extent ha un segmento di rollback, tanto più
frammentato potrebbe essere lo spazio da esso occupato. Per esempio,
consideriamo un segmento di rollback di 200MB suddiviso in due
extents di 100MB ognuna. Se questo segmento dovesse richiedere
dello spazio supplementare, si creerebbe un altro extent di 100MB.
Ciò farebbe aumentare la grandezza del segmento di rollback
del 50 per cento senza che tutto questo spazio in più sia
realmente necessario. Al contrario, se il segmento di rollback
fosse composto da 20 extent di 10MB, tutto lo spazio aggiunto
sarebbe di soli 10MB. Quando un segmento di rollback è
costituito da 20 o più extent, ogni singolo cambiamento
nel numero di extent non modificherà la grandezza totale
del segmento di rollback più del 5 per cento.
Detto questo, aumentare il numero di extent oltre i 20 suggeriti
renderà la ripartizione dello spazio ancora più
regolare. Tuttavia, aumentare e diminuire le extent non è
un operazione senza costi. La base dati avvertirà la degradazione
di prestazioni quando ad un segmento di rollback è costantemente
assegnato e/o cancellato l'assegnazione di extent.
Una query non vede mai i cambiamenti fatti ai dati dalle transazioni
che committano durante il corso dell'esecuzione della query. Oracle
identifica unicamente dei punti nel tempo con un insieme di numeri
chiamati System Change Numbers (numeri di cambiamento del sistema).
Si pensi allo SCN come la condizione della base dati in un determinato
momento. Quando una query inizia la sua esecuzione, oracle gli
assegna uno SCN. La query può vedere soltanto lo snapshot
(la fotografia) dei record così come sono nel momento in
cui gli e stato assegnato l SCN. Ogni volta che una transazione
effettua una modifica dei dati viene effettuato uno snapshot del
record che verra modificato, in un segmento di rollback a cui
verrà assegnato un proprio indirizzo
Se ci sono dati non committati da altre transazioni, oppure ci
sono modifiche in corso con un SCN più-recente, allora
i dati saranno ricostruiti usando lo snapshot salvato dai segmenti
di rollback. Un segmento di rollback conserva lo snapshot dei
dati cambiati finchè la transazione è ancora attiva
(cioè non è stato eseguito un rollback o una commit).
Una volta che una transazione è committata, la base dati
la contrassegna con uno SCN corrente e lo spazio usato dallo snapshot
diventa riutilizzabile. Di conseguenza, un errore Ora-01555 accadrà
se la query sta cercando uno snapshot che è così
vecchio che le informazioni di segmento di rollback non potrebbero
essere trovate.
Se la basedati ha molte transazioni che cambiano i dati e committano
molto spesso, come in un ambiente di elaborazione di transazioni
in linea (OLTP), la probabilità di riutilizzare lo spazio
usato da una transazione è più alto. Una query in
esecuzione da molto tempo allora non può creare lo snapshot.
I più grandi segmenti di rollback in questo caso ridurranno
la probabilità di riutilizzazione delle scanalature committate
dalle transazione.
In questo caso dovreste studiare la possibilità di aggiungere
più segmenti di rollback e di aumentare la loro grandezza.
Il formato ed il numero dei segmenti di rollback dipendono dalle
richieste della vostra applicazione e del numero di utenti connessi
contemporaneamente.
Nella clausola di rollback, cè un parametro chiamato
OPTIMAL che specifica il segmento ottimale di rollback in byte.
Quando questo è settato, la basedati proverà a mantenere
al segmento il formato specificato. Se è necessario dello
spazio supplementare oltre il formato ottimale, il segmento di
rollback si espanderà oltre il formato ottimale per accomodare
la transazione corrente, ma quindi cancellerà l'assegnazione
dellextent per ritornare di nuovo al formato specificato.
Quando il parametro OPTIMAL è troppo basso, potrebbe causare
l errore Ora-01555.
Per fornire le prestazioni migliori, bisognerebbe settare tutti
i segmenti di rollback ad un formato adeguato ad ogni singola
transazione. In pratica però questo potrebbe essere impossibile,
per esempio, se la transazione è 500MB e il numero di segmenti
di rollback è 30.
La grandezza ottimale dei segmenti dovrebbe essere tale che il
90 per cento delle transazioni non richiedano estensioni dei segmenti.
In più, la tablespace di rollback dovrebbe essere abbastanza
grande in modo che quando tutti i segmenti di rollback sono al
valore ottimale, ci sia abbondanza di spazio affinchè si
possano estendere quando diventa necessario. Per esempio, se i
segmenti sono regolati con un valore ottimale di 50MB e sapete
che c è una transazione particolare che viene eseguita
raramente, ma richiede 1GB, la tablespace di rollback dovrebbe
avere almeno 950MB liberi quando tutti i segmenti in quella tablespace
sono al formato ottimale. Poiché non è possibile
avere tutti i segmenti alla grandezza ottimale o che la transazione
sia lunica ad utilizzare il segmento di rollback, si dovrebbe
avere almeno dal 30 al 40 per cento di spazio disponibile in più
.
Se invece un segmento di rollback è corrotto e non può
essere letto, sarà necessario droppare e ricreare il segmento
di rollback.
È possibile droppare un segmento di rollback soltanto se
è offline. Per determinare se un segmento di rollback è
offline, è necessario interrogare la vista del data dictionary
DBA_ROLLBACK_SEGS. I segmenti di rollback offline hanno il valore
dello STATUS ad AVAILABLE, mentre i segmenti offline hanno il
valore di STATUS ad IN_USE.
Per portare offline dei segmenti di rillback basta eseguire il
seguente comando:
ALTER ROLLBACK SEGMENT nome rallback OFFLINE;
DROP ROLLBACK SEGMENT nome rallback;
Quando viene generato un segmento di rollback, è inizialmente
offline, e per portarlo on-line basta eseguire il seguente comando
in cui viene specificata la tablespace altrimenti Oracle lo genererà
nalla tablespace di sistema
CREATE ROLLBACK SEGMENT nome rallback TABLESPACE
nome tablespace;
ALTER ROLLBACK SEGMENT nome rallback ONLINE;
Per aggiornare, cancellare o creare un segmento di rollback è
necessario avere i privilegi relativi (ALTER ROLLBACK SEGMENT,
DROP ROLLBACK SEGMENT, and CREATE ROLLBACK SEGMENT) .