A fronte di malfunzionamenti hardware (rottura di un disco), software (anomalie di sistema), errori umani (cancellazione di file) possono verificarsi perdite di dati sullRDBMS Oracle.
Una completa discussione dellargomento del recovery, cui si rimanda per la maggior parte dei problemi che possono verificarsi, e contenuta nel DBA Guide (o Server Guide).
In alcuni casi e possibile risolvere il problema o addirittura aggirare i controlli di correttezza di Oracle e consentire una operativa anche su un sistema non piu stabile.
Poiche' alcune modalita' non sono documentate (o almeno non espressamente) ho pensato utile riportarle su questo documento.
Nessuna procedura di ripristino potra' mai funzionare se non sono soddisfatte le seguenti due condizioni:
E' pertanto necessario:
Su sistemi di produzione cio' significa aver impostato un piano di backup ed aver preparato, documentato, provato diverse modalita' di ripristino.
Prima di utilizzare una qualsiasi procedura di ripristino dati effettuare un salvataggio completo del sistema/base dati.
Un'ultima avvertenza molti dei comandi contenuti in questo documento sono pericolosi se usati in modo non corretto: utilizzateli se sapete cosa state facendo.
Altri documenti contengono utili informazioni sull'argomento. Tra gli altri: Utilizzo della modalita' di log archiving in Oracle, Backup a tempo di Oracle su NT,
Per i casi piu' semplici... non ci sarebbe nulla da dire!
Se avete un backup fisico (attenzione va effettuato con l'RDBMS spento se non
e' attivo il log archiving), basta ripristinare e far ripartire il DB.
Se avete un backup logico potete recuperare i dati con l'utility imp.
Se la vostra versione di Oracle e' recente potete utilizzare RMAN ed impdp...
L'importante e' saperli usare!
In effetti le possibilita' sono parecchie, vanno valutate con attenzione ed un ripristino
errato puo' generare ancora piu' danni!
Spesso prima di effettuare un ripristino e' opportuno effettuare nuovamente un salvataggio.
Istanze o sistemi di appoggio sono spesso utili. Sempre utile e' l'abbondanza di spazio disco.
E' molto importante salvare i log e tenere una traccia delle operazioni effettuate.
...
Con i ripristini logici a volte e' necessario ricompilare procedure e package. Utili sono: EXEC DBMS_UTILITY.compile_schema(schema => 'SCOTT', compile_all => false) e $ORACLE_HOME/rdbms/admin/utlrp.sql
Nel caso in cui vi siano dei blocchi errati nel database (la loro determinazione e possibile analizzando i file di trace in $ORACLE_HOME/rdbms/log) E' possibile utilizzare alcuni trucchi per effetture comunque le operazioni richieste.
Sui file di alert e' riportato il numero di file ed il blocco in errore (in decimale). Questi vanno convertiti in esadecimale per confrontarli con i rowid (eg. file #12 block 108117 corrisponde a rowid 0001A655.%.000C). La selezione per deteminare l'oggetto contenente il blocco in errore e' la seguente:
select * from dba_extents where file_id=12 and 108117 between block_id and block_id+blocks-1 OWNER ------------------------------ SEGMENT_NAME -------------------------------------------------------------------------------- SEGMENT_TYPE TABLESPACE_NAME EXTENT_ID FILE_ID ----------------- ------------------------------ ---------- ---------- BLOCK_ID BYTES BLOCKS ---------- ---------- ---------- SCOTT EMP TABLE TAB_XYZ 2 12 103039 209715200 6400
I problemi sono come le ciliege: i blocchi corrotti non vengono mai da soli!
Quando si verifica qualche corruzione conviene controllare tutti i datafile.
Utile e' il comando Oracle di DB Verify:
dbv file=users01.dbf
Utilizzando RMAN i blocchi corrotti trovati durante durante un salvataggio vengono raccolti sulla vista V$DATABASE_BLOCK_CORRUPTION. Utile e' in questo caso la select:
select substr(e.owner||'.'||e.segment_name ||' on '||e.tablespace_name , 40) Object, 'File: '||e.file_id || ' Block: '||d.block#||' '|| d.corruption_type from dba_extents e, v$database_block_corruption d where file_id=file# and block# between block_id and block_id+e.blocks-1;
Nel caso di indici il problema non si pone (o meglio e' facile da risolvere). Gli indici vanno semplicemente ricreati. Sono stati rilevati alcuni casi in cui Oracle (probabilmente per un bug) puo' sporcare alcuni blocchi di indice.
Generalmente la segnalazione e' esplicita (ovvero la sessione muore e sul trace sono riportati i blocchi errati), in altri casi il problema viene riportato come ORA-600 (il fatidico internal error) che e', in questo caso, facilmente risolvibile ricreando l'indice.
Ovviamente in caso di blocchi corrotti su indice non e' possibile utilizzare la clausola REBUILD...
Il generale i trucchi consistono nellevitare di accedere ai blocchi errati (poiche quando vi si accede lo statement SQL fallisce) con condizioni particolari. E' per esempio possibile escludere dalla selezioni blocchi (fisici) di dati con una clausola sul rowid (per sapere quali blocchi saltare e' sufficiente controllare quali sono i blocchi che risultano corrotti e che vengono riportati sui file di trace).
Ad esempio:create table emp_save unrecoverable storage (initial 200M next 200M) tablespace tab_xyz as select /*+ INDEX(EMP PK_EMP) */ ename, ... from emp;
Accedendo agli indici e' possibile risalire a tutti i dati delle colonne indicizzate (se una select puo' essere eseguita accedendo ai soli dati di un indici Oracle giustamente non effettua accessi ai blocchi della tabella: cosi' lo statement SQL non fallisce).
In tal modo si riescono ad effettuare selezioni riuscendo cosi' a salvare i dati su altre tabelle.
E' poi necessario provvedere alla ricostruzione del tablespace.
In caso di corruzione di un datafile, se e' attiva la modalita' di ARCHIVELOG, e' possibile ripristinare da backup il datafile corrotto e quindi attivare il recovery giungendo sino all'ultima transazione committata.
Se il database non ha l'ARCHIVELOG tale possibilita' non e' presente e bisogna ripartire completamente da backup fisico. In alcuni casi fortunati tuttavia (quando i redo log relativi alle operazioni svolte non sono ancora stati riutilizzati) e' possibile effettuare comunque con successo un alter database recover poiche' agisce sugli on-line redo.
Infine in alcuni casi e' possibile effettuare un RECOVER UNTIL CANCEL ed, anziche' applicare quanto suggerito (eg. /oracle/arch/...), applicare un REDO LOG.
Quando un datafile riporta alcuni gravi problemi l'intero tablespace viene posto offline. E' pero' possibile porre un datafile offline mantenendo comunque attivo il tablespace che lo contiene. Ovviamente tutti i dati eventualmente presenti sul datafile posto offline verranno perduti.
Il comando e' documentato solo nei manuali delle ultime versioni di Oracle (e' pero' presente anche nelle precedenti 7.X).
ALTER DATABASE DATAFILE '/usr/oracle/dbs/data03.dbf' OFFLINE DROP;
Il caricamento di un RDBMS a partire da un salvataggio logico puo' essere una attivita' di lunga durata.
L'utilizzo di un import e' in molti casi una necessita' quando si voglia ripristinare soltanto un insieme di tabelle (e naturalmente si disponga di un export). Questo tipicamente avviene a fronte di errori in applicazioni o nelle operative piuttosto che a causa di rotture su dischi. L'errore umano e', per esperienza personale, molto piu' frequente di quello meccanico.
Per avere le prestazioni migliori puo' essere utile seguire alcuni consigli:
Puo' essere in alcuni casi opportuno ribaltare il contenuto di un'instanza su una seconda.
La procedura da seguire consiste nei seguenti passi:
Per ricreare i control file e rinominare un'istanza e' necessario:
STARTUP NOMOUNT CREATE CONTROLFILE REUSE SET DATABASE "COPIA" RESETLOGS NOARCHIVELOG MAXLOGFILES 32 MAXLOGMEMBERS 2 MAXDATAFILES 64 MAXINSTANCES 8 MAXLOGHISTORY 800 LOGFILE GROUP 1 '/usr/oracle/dbs/COPIA/redo01.log' SIZE 20M, GROUP 2 '/usr/oracle/dbs/COPIA/redo02.log' SIZE 20M, GROUP 3 '/usr/oracle/dbs/COPIA/redo03.log' SIZE 20M DATAFILE '/usr/oracle/dbs/COPIA/system.dbf', '/usr/oracle/dbs/COPIA/rbs.dbf', '/usr/oracle/dbs/COPIA/temp.dbf', '/usr/oracle/dbs/COPIA/d001.dbf', '/usr/oracle/dbs/COPIA/i001.dbf'; ALTER DATABASE OPEN RESETLOGS; ALTER DATABASE RENAME global_name TO NUOVO;
Per generare lo script SQL per la rigenerazione dei control file puo' essere comodo utilizzare il comando ALTER DATABASE BACKUP CONTROLFILE TO TRACE che genera un file di trace con gli statement SQL necessari (attenzione: deve poi essere corretto con le istruzioni necessarie).
Nel caso in cui si verifichino casi di blocchi corrotti nei rollback e' necessario utilizzare una procedura particolare.
Il segmento di rollback entra in stato di NEED RECOVERY. Non e' possibile cancellarlo poiche' non e' offline, non e' possibile renderlo offline poiche' non e' disponibile, non e' possibile cancellare il tablespace che lo contiene poiche' viene trovato un rollback attivo sul tablespace. Uffa!
E' pertanto necessario escludere dall'elenco dei rollback i rollback corrotti nel file initSID.ora, inserire nello stesso file il comando _corrupted_rollback_segments = rXYZ (NB parametro non documentato) e far risalire la base dati. A questo punto e' possibile cancellare i segmenti di rollback.
Alcuni casi meno gravi possono essere risolti ponendo semplicemente fuori linea i segmenti di rollback con il parametro _offline_rollback_segments= rXYZ. Il caso banale di rollback non presente ha la ovvia soluzione di non inserire il nome del rollback nell'init.ora.
Queste situazioni sono comunque a "rischio" ed e' molto probabile si presentino errori ORA-600 o simili.
Problemi su REDO LOG non in linea o su copie di mirror vengono risolti facilmente con le relative istruzioni SQL (eg. SELECT * FROM V$LOGFILE; ALTER DATABASE SWITCH LOGFILE; ALTER DATABASE CLEAR [UNARCHIVED] LOGFILE GROUP XYZ; ...).
Nel caso in cui gli online REDO LOG siano corrotti sarebbe necessario effettuare un ripristino dell'RDBMS da backup. Se non e' attiva la modalita' di log archiving quindi si perdono tutti i dati modificati dall'ultimo backup.
E' possibile seguire una procedura alternativa:
Il fatto che la procedura non sia documentata non e' dovuto a dimenticanza: sono presenti grossi rischi, quindi la procedura indicata va utilizzata solo in caso di assoluta necessita'.
In qualche fortunato caso la base dati non vuole saperne affatto di ripartire... Tali situazioni si presentano tipicamente per una serie di cause e problemi distinti (ad esempio problemi HW, backup online interrotti durante l'esecuzione, fault avvenuti durante attivita' di modifica sul data dictionary, ...).
In tali condizioni la situazione e' corrotta e la base dati non vuole ripartire. Tuttavia puo' essere comunque necessario riattivare l'istanza...
Vi sono parecchi parametri da inserire nell'init.ora o da definire in modo interattivo non documentati e non supportati che l'Hot Line Oracle puo' indicare. Si tratta in generale di opzioni che fanno "saltare" qualche controllo al motore Oracle e possono essere specifici di particolari versioni. Non debbono pertanto essere utilizzati senza il supporto di Oracle (perche' allora ne parlo? Perche' e' importante sapere che ci sono tali possibilita'!).
Ad esempio con:
SVRMGRL> connect internal SVRMGRL> startup mount SVRMGRL> alter session set events '10228 trace name adjust_scn level 100'; SVRMGRL> alter database open
si cerca di far risalire una base dati anche se gli SCN non sono allineati (i
Change Number indicano i livelli di aggiornamento dei blocchi nei datafile).
Vi sono programmi in grado di accedere
direttamente ai dati sui datafile senza utilizzare l'RDBMS Oracle. Tali programmi
possono pertanto operare anche su singoli datafile ed a database non attivo.
DUL e' il programma a disposizione
del personale Oracle (non distribuito) per effettuare tali recuperi in situazioni
di reale emergenza. Citando il DUL: Life is DUL without need of it.
Prodotti con funzionalita' simili sono
anche forniti da terze parti. Naturalmente vanno acquistati...
A volte i miracoli non bastano, puo' capitare
di perdere tutto senza possibilita' di recupero. Auguri!
Testo: Attivita' di
recovery sull'RDBMS Oracle
Data: 30 Febbraio 1998
Versione: 1.1.9
Autore: mail@meo.bogliolo.name, Fabio Maggiora