I piu' comuni errori su Oracle

Quando si utilizza uno strumento per le prime volte si possono commettere errori. Uno strumento potente, ma complesso, come l'RDBMS Oracle inganna parecchi programmatori ed utenti che commettono spesso errori dovuti all'inesperienza.

Poiche' le situazioni sono pressoche' sempre le medesime in questa breve guida sono riportate le indicazioni per evitare gli errori ed i problemi piu' comuni.
Questo documento riporta i piu' comuni errori Oracle (nel senso di codice d'errore). Dopo una breve introduzione sulle caratteristiche di Oracle e sul formato degli errori sono riportati i piu' comuni errori che vengono restituiti da Oracle. Anche se non e' possibile una distinzione precisa, alcuni errori sono di maggior interesse per i programmatori mentre altri riguardano maggiormente i DBA (DataBase Administrator). La distinzione non e' comunque importante: la sfiga accomuna tutti gli informatici.
Il documento I piu' comuni problemi su Oracle riporta invece le problematiche piu' comuni in tale ambiente (ma che non generano codici d'errore specifici).

Le segnalazioni d'errore di Oracle sono migliaia... questo documento riporta solo alcune situazioni che ritengo tra le piu' comuni!


Perche' tanti errori?

Oracle ha una serie di caratteristiche che lo rendono un RDBMS molto completo, potente ed adatto a basi dati di grandi dimensioni, complesse e con un numero di accessi molto elevati. Al tempo stesso queste caratteristiche lo rendono un poco piu' complesso, almeno come primo approccio.

Tra le peculiarita' di Oracle che lo differenziano da altri gestori di basi dati e che lo rendono un poco piu' complesso e' possibile raggruppare su alcuni temi:


Il formato degli errori

Gli errori Oracle seguono una precisa codifica. La prima parte e' di tre caratteri ed indica il prodotto/funzione Oracle che ha rilevato l'errore (eg. ORA per i problemi sull'Oracle Server, PLS per i problemi in PL/SQL, ...); la seconda parte e' un numero, fino a cinque cifre, univoco che identifica l'errore. I valori degli errori hanno range precisi; ad esempio un valore tra 6600 e 6700 indica un errore SQL*Net.

Questo capitoletto non lo volevo scrivere. Ma l'ho scritto ugualmente e lo dedico ad un'amica perche' sembra che tutti le vogliano spiegare cos'e' un errore su Oracle!


ORA-1555 snapshot too old: rollback segment too small

Il problema si presenta su selezioni di lunga durata su tabelle sottoposte a modifica.

Oracle assicura la read consistency sugli statement SQL. Questo vuol dire che quando si lancia una selezione tutti i dati si riferiscono allo stesso "istante", dalla prima all'ultima riga selezionata, per tutto il tempo della durata dell'elaborazione e per quante modifiche siano effettuate sulle tabelle selezionate.

Per mantenere tale consistenza Oracle, in caso di modifiche alla tabella selezionata, e' costretto a leggere i dati sui segmenti di rollback. Questo comporta alcuni problemi: l'accesso a segmenti di rollback anziche' rallenta, spesso in modo considerevole, l'accesso ai dati; inoltre, se le modifiche sono molto frequenti, la selezione dei dati puo' fallire con l'errore ORA-1555 poiche' non e' piu' in grado di accedere a dati cosi' "vecchi".

Ovviamente il problema si presenta solo se vi sono transazioni che agiscono in modifica sui dati selezionati. Evitando tale concorrenza il problema non si presenta. Deve essere notato che il problema puo' presentarsi anche se e' presente una sola applicazione che mantiene un cursore aperto su una tabella su cui sta effettuando modifiche.

Dal punto di vista del sistema e' possibile aumentare la dimensione dei rollback segment. Tuttavia questa NON e' sempre la soluzione corretta. La crescita di dimensione dei rollback segment ha infatti pesanti ripercussioni in termini di spazio e di prestazioni. Inoltre la crescita oltre certe dimensioni non risolve comunque il problema (nonostante la descrizione dell'errore).
La soluzione corretta, generalmente semplice dal punto di vista applicativo, e' quella di utilizzare selezioni specifiche di minor durata segmentando i dati.
Nel caso particolare di una sola applicazione che seleziona gli stessi dati che sta modificando e' possibile evitare il problema non effettuando commit (anche se questo puo' generare un altro problema!).

In conclusione e' errato mantenere cursori aperti per un lungo periodo se vi sono in corso modifiche ai dati.


SQL-2112 SELECT..INTO returns too many rows

Questo e' un classico! All'interno di una applicazione si trova un statement di SELECT che utilizza la clausola INTO per porre in una serie di Host Variables il risultato.

E' un problema della query utilizzata (o peggio sui dati presenti nella base dati).


ORA-60 deadlock detected while waiting for resource

Il problema si presenta in presenza di piu' applicazioni che accedono in modifica agli stessi dati in modo non "ordinato" (leggi corretto).

Ad esempio: l'applicazione A blocca la riga X, l'applicazione B blocca la riga Y, l'applicazione cerca di bloccare la riga Y (e va in attesa), l'applicazione B cerca di bloccare la riga X. A questo punto entrambe le applicazioni si bloccano a vicenda. Oracle si accorge del problema ed effettua un rollback sulla transazione piu' "giovane". In tal modo almeno una applicazione puo' proseguire e, al termine della transazione, rilasciare i lock e consentire ad altre applicazioni di agire sugli stessi dati.

E' un errore comune nelle applicazioni Oracle. La soluzione e' applicativa. Sono possibili diversi approcci. La prima possibilita' e' quella di eseguire prima l'applicazione A e poi l'applicazione B (banale). Generalmente si cerca di porre in lock righe nello stesso ordine (ordinato), altrimenti si usa cercare di riservarsi tutti i lock all'inizio della transazione (previdente), utilizzare il lock non sospensivo (c'e' qualcuno?) o si riprova in continuazione (ritenta sarai piu' fortunato).

In conclusione e' errato porre lock in modo disordinato sui dati Oracle. Le transazioni vanno correttamente disegnate e l'ordine di accesso ai dati definito.


ORA-54 resource busy and acquire with NOWAIT specified

Il problema e' semplice: c'e' gia' qualcuno che sta utilizzando lo stesso oggetto su cui volete lavorare anche voi! C'e' un LOCK attivo

Soluzione: aspettare! Se non avete pazienza potete cercare di capire chi sta utilizzando l'oggetto su cui avete richiesto un lock (ci sono selezioni su viste di sistema che il vostro amato DBA conosce bene).


ORA-1017 invalid username/password; logon denied

Il problema e' banale. Lo username o la password sono sbagliati!
L'ho riportato perche' il numero di volte che questo problema avviene e' enorme. Naturalmente il primo posto in classifica l'hanno gli utenti che dimenticano la password.
Ma e' molto comune anche utilizzare username e password corrette e sbagliare base dati (ORACLE_SID, configurazione TNS_NAMES, ...)!
Infine anche se l'errore e' banale, spesso viene nascosto in modo quasi perfetto dall'applicazione. Cosi' si cerca magari a lungo qualche strano problema quando la soluzione e' semplicissima.

La soluzione e' troppo banale: usate la password giusta!


ORA-1422 exect fetch return more than the requested number of rows

Qui c'e' proprio un bachetto! Una selezione che utilizza la clausola INTO per raccogliere il risultato su una variabile contiene un errore. Infatti anziche restituire una sola riga (in una variabile C o Cobol, ... e' possibile avere un solo valore per ogni variabile) restituisce un insieme di valori.

E' necessario correggere la selezione. In generale e' sufficiente correggere la selezione in modo che la riga restituita sia una sola (con l'eventuale trucco del ROWNUM). In qualche caso e' necessario cambiare la logica del programma e trattare le variabili con il classico ciclo di OPEN e FETCH.


ORA-100, ORA-1403 no data found

Non e' proprio un errore: semplicemente non ci sono piu' dati!

Poiche' non e' un errore non ci sono soluzioni!
Se davvero vi aspettavate qualche riga come risultato controllate la clausola di WHERE ed i dati sul DB...


ORA-1 unique constraint table.column violated

Non si puo' introdurre due volte un dato con la stessa chiave!

Chiaro no?!


ORA-1658 unable to create INITIAL extent for segment in tablespace name

Quando Oracle crea un oggetto cerca, all'interno del tablespace su cui l'oggetto verra' creato, uno spazio libero contiguo per il segmento iniziale di dati. Se questo spazio non e' disponile viene generato l'errore.

Le ragioni possono essere diverse. Innanzi tutto la mancanza di spazio. In questo caso il tablespace che ospita l'oggetto deve essere allargato inserendo un nuovo datafile o allargando uno dei datafile esistenti. Naturalmente si deve avere a disposizione sufficiente spazio disco nel sistema per poterlo allocare alla base dati.
Ma e' anche possibile che sia errato il tablespace su cui Oracle crea il segmento iniziale, infatti vi e' un default per ogni utente ma e' possibile far creare un oggetto sul tablespace corretto specificandolo nella clausola di STORAGE.
Infine la dimensione iniziale potrebbe essere esagerata. Questo puo' avvenire sia per un errore nella sua definizione che perche' non definito (ed in questo caso ad essere esagerata e' la dimensione di default per tablespace). Anche in questo caso si deve indicare il valore corretto nella clausola di STORAGE.

Spesso lo spazio libero sul tablespace sarebbe sufficiente per l'allocazione ma lo spazio non e' contiguo. In questo caso e' necessario effettettuare una riorganizzazione della base dati (generalmente con un export/import).


ORA-1650 unable to extend rollback segment name by n in tablespace name
ORA-1652 unable to extend temp segment by n in tablespace tablespacename
ORA-1653 unable to extend table owner.name by n in tablespace name
ORA-1654 unable to extend index owner.name by n in tablespace name
ORA-1654 unable to extend cluster owner.name by n in tablespace name

Questi problemi sono simili al precedente ORA-1658 con la differenza che l'oggetto gia' esiste. Il segmento iniziale non era piu' sufficiente a contenere tutti i dati quindi Oracle ha creato nuovi extent fino ad esaurire lo spazio presente.

Se a scoppiare e' un rollback segment allora la ragione e' da ricercare in una transazione che effettua troppe modifiche prima di effettuare un COMMIT. Spesso non e' giustificato (ed inutile) variare la dimensione dei rollback in questo caso.
Se a scoppiare e' un segmento temporaneo allora la ragione puo' essere un SORT (implicito o esplicito) su troppi record. A volte si tratta di selezioni dati non corrette...

Il problema e' spesso dovuto ad un errato dimensionamento dell'oggetto. Oltre alle indicazioni gia' date (spazio disco insufficiente, tablespace errato, INITIAL esagerato, frammentazione dello spazio libero) possono essere errati i parametri di storage di NEXT e PCTINCREASE che vanno quindi controllati ed eventualmente corretti.


ORA-1628 max # of extents n reached for rollback segment n
ORA-1630 max # of extents n reached temp segment in tablespace name
ORA-1631 max # of extents n reached in table name
ORA-1632 max # of extents n reached in index name
ORA-1656 max # of extents n reached in cluster name

L'oggetto in questione ha raggiunto il massimo numero di extent. C'e' un limite a tutto. Anche Oracle a volte dice: "Me lo hai fatto a fette!"

Per i rollback ed i temporanei valgono anche le indicazioni gia' date in precedenza sulla mancanza di spazio sulla creazione di extent.

Come soluzione temporanea aumentate il limite massimo sul numero di extent dell'oggetto (possibile dalle ultime versioni di Oracle).
La soluzione definitiva e' comunque quella di cancellare l'oggetto e ricrearlo con il dimensionamento corretto.


ORA-600 internal error code, arguments:n,n,n,n,n,n

Ahi, Ahi! Oracle ha trovato un problema al suo interno. Puo' essere un baco di Oracle (succede) o una corruzione di dati (succede anche questo).

Aprite una chiamata al supporto Oracle. Cercate di capire qual'e' la causa scatenante, se l'errore si ripresenta, in quali condizioni,...
Fatevi un bel salvataggio (meglio due: logico e fisico) della base dati e cominciate a controllare i vecchi backup...


ORA-pro nobis

Questo documento e' in perenne costruzione! Quando trovero' qualche altra simpatica spiegazione di un simpatico errore la aggiungero'.

Per il momento comunque mi sembra che basti cosi'! Quindi se non sai piu' che fare... inizia a pregare!


Testo: I piu' comuni errori su Oracle
Data: 17 Giugno 1997
Versione: 1.2.1
Autore: mail@meo.bogliolo.name