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 (eg. la maggioranza iniziano con ORA- )
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 cosi' 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!
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:
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!
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.
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).
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.
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).
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!
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.
Non e' proprio un errore: semplicemente non ci sono piu' dati!
Poiche' non e' un errore non ci sono soluzioni!
Non si puo' introdurre due volte un dato con la stessa chiave!
Chiaro no?!
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. 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).
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. 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.
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).
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,...
Sul sito di supporto Oracle [NdA MOS o Metalink per i nostalgici]
e' da tempo presente un tool per effettuare una prima diagnosi
[NdA ORA-600/ORA-7445/ORA-700 Error Look-up Tool (Doc ID 153788.1)]:
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 ORA-basta cosi'. Quindi se non sai piu' che fare... inizia a pregare!
Testo: I piu' comuni errori su Oracle
Se davvero vi aspettavate qualche riga come risultato controllate
la clausola di WHERE ed i dati sul DB...
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.
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
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...
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
La soluzione definitiva e' comunque quella di cancellare l'oggetto e ricrearlo
con il dimensionamento corretto.
Fatevi un bel salvataggio (meglio due: logico e fisico) della base dati e cominciate
a controllare i vecchi backup...
[NdA ORA in latino significa prega]
Data: 17 Giugno 1997
Versione: 1.2.3
Autore: mail@meo.bogliolo.name