Corruzione Blocchi in Oracle 10g

mercoledì 28 maggio 2008 alle 28:51 | Pubblicato su Backup and Recovery, Installation and Configuration | 6 commenti

In questi giorni ho fatto un po’ di ricerca e test sui metodi di ricerca e correzione dei problemi di corruzione dei dati in Oracle. Per corruzione intendo corruzione fisica e logica, ma non applicativa, nel senso che non parliamo ad esempio di dati non consistenti dal punto di vista applicativo (ad esempio un tabella righe ordine con record che puntano a testate non esistenti).
Escluse quindi le corruzioni di tipo applicative rimangono a livello oracle le corruzioni fisiche, ovvero le corruzioni dovute a problemi hardware, e le corruzioni logiche che possono essere dovute a bachi o malfunzionamenti di Oracle, o del sistema operativo, ma anche a malfunzionamenti hardware.
Oracle a livello di sistema prevede due tipi di controllo, attivati tramite due parametri:

  • DB_BLOCK_CHECKSUM
  • DB_BLOCK_CHECKING

DB_BLOCK_CHECKSUM

In breve questo parametro attiva un controllo volto a individuare per tempo corruzioni di tipo fisiche. Il controllo consiste nel calcolare un “checksum” sul contenuto di un blocco e salvarlo sull’header del blocco stesso quando questo viene scritto su disco. Poi alla lettura del blocco tale checksum viene ricontrollato. Il parametro può assumere i valori OFF (nessuno controllo), TYPICAL (il checksum viene ricontrollato ad ogni lettura del blocco dal disco), FULL (il checksum viene ricontrollato anche ad ogni modifica dei dati nel blocco. Il default secondo la documentazione è TYPICAL, ma sui miei database trovo sempre TRUE che però sempre secondo la documentazione è equivalente e viene mantenuto per compatibilità. Analogamente il valore FALSE è equivalente a OFF.

DB_BLOCK_CHECKING

Questo parametro permette di attivare dei controlli sulla consistenza logica dei blocchi. Credo che indirettamente questi controlli possano rilevare anche problemi fisici come quelli che rilava il controllo attivato tramite DB_BLOCK_CHECKSUM. DB_BLOCK_CHECKING accetta quattro possibili valori, corrispondenti a quattro livelli di controllo:

  • OFF (per compatibilità viene accettato anche FALSE) nessun controllo, a parte per la tablespace SYSTEM per cui è sempre attivo il controllo semantico sui blocchi
  • LOW vengono fatti dei controlli base ad ogni modifica del contenuto di un blocco (ad esempio conseguenti ad operazioni di INSERT o UPDATE).
  • MEDIUM vengono fatti gli stessi controlli attivati con LOW più un controllo semantico sui blocchi (quello sempre attivo per la tablespace SYSTEM) per tutti i blocchi delle tabelle che non siano di tipo IOT.
  • FULL (per compatibilità viene accettato anche TRUE) vengono fatti tutti i controlli fatti con le impostazioni LOW e MEDIUM più il controllo semantico anche per i blocchi degli indici.

Per default questo parametro è settato a FALSE (OFF). L’attivazione di questo controllo secondo Oracle porta un sovraccarico che va dall’1% al 10%.

DBVERIFY

Oracle fornisce un’utility, chiamata dbverify, che è esterna al database e quindi può lavorare anche a database fermo, per controllare l’integrità dei datafile. La documentazione non è molto dettagliata sul tipo di controlli effettuati da questa utility ma da alcuni test fatti da me pare che faccia sia i controlli effettuati di checksum che contolli sull’integrità logica dei blocchi.
Ecco un esempio:

[oracle@testrman udump]$ dbv blocksize=8192 file=/opt/oracle/oradata/test102/use        rs01.dbf

DBVERIFY: Release 10.2.0.4.0 - Production on Tue May 27 12:06:07 2008

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

DBVERIFY - Verification starting : FILE = /opt/oracle/oradata/test102/users01.dbf
Block Checking: DBA = 16881510, Block Type = KTB-managed data block
data header at 0x2a96f11264
kdbchk: the amount of space used is not equal to block size
        used=7356 fsc=0 avsp=847 dtl=8088
Page 104294 failed with check code 6110

DBVERIFY - Verification complete

Total Pages Examined         : 119520
Total Pages Processed (Data) : 103078
Total Pages Failing   (Data) : 1
Total Pages Processed (Index): 1753
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 6084
Total Pages Processed (Seg)  : 0
Total Pages Failing   (Seg)  : 0
Total Pages Empty            : 8605
Total Pages Marked Corrupt   : 0
Total Pages Influx           : 0
Highest block SCN            : 8598290 (0.8598290)

Io ho fatto dei test brutali usando, su una macchina linux, il comando dd per corrompere un blocco. Ho dovuto disattivare DB_BLOCK_CHECKSUM, altrimenti:

SQL> select d, e from testbr where aid=1000151;
select d, e from testbr where aid=1000151
                 *
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 4, block # 104294)
ORA-01110: data file 4: '/opt/oracle/oradata/test102/users01.dbf'

DBMS_REPAIR

Un’altro strumento che Oracle fornisce per la gestione di corruzioni logiche di blocchi è il package PL/SQL DMBS_REPAIR. Per conto mio ha un’utilità molto limitata, ma fa parte della preparazione per l’esame OCP. Questo package comprende una serie di procedure che servono ad analizzare Oggetti di database, similmente ha quanto fa il database con il settaggio del parametro DB_BLOCK_CHECKING e DBVERIFY, ma qui il controllo viene fatto per oggetto (tabelle, indici, …).

Tramite la procedura CHECK_OBJECT si controlla lo stato di integrità di un oggetto. Il risultato dell’analisi fatta dalla procedura viene messo in una tabella. Ad esempio, la stessa corruzione individuata trami dbverify nell’esempio precedente:

CORRUPT_DESCRIPTION
---------------------------------------------------------------------
Block Checking: DBA = 16881510, Block Type = KTB-managed data block
data header at 0x70fa4064
kdbchk: the amount of space used is not equal to block size
        used=7356 fsc=0 avsp=847 dtl=8088
mark block software corrupt

Corruzioni del tipo sopra, in questo caso creata artificialmente da me possono provocare comportamenti anomali del database, nel mio caso:

SQL>  select d, e from testbr where aid=1000150;
ERROR:
ORA-03113: end-of-file on communication channel

no rows selected

ERROR:
ORA-03114: not connected to ORACLE

Con la stampa di errori sull’alert. Il package DBMS_REPAIR fornisce una procedura FIX_CORRUPT_BLOCK che marca come corrotti i blocchi precedentemente indivuduati. Dopo aver lanciato questa procedura:

SQL> select d, e from testbr where aid=1000150;
select d, e from testbr where aid=1000150
                 *
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 4, block # 104294)
ORA-01110: data file 4: '/opt/oracle/oradata/test102/users01.dbf'

Per evitare di beccarsi questo errore si può indicare a Oracle di saltare il blocco corrotto con la procedura SKIP_CORRUPT_BLOCKS. Questo non permette di recuperare i dati che erano contenuti nel blocco corrotto, quelli rimangono persi. Con queste procedure però si può continuare a interrogare il resto della tabella. Per questo motivo non reputo questo package molto interessante
BLOCKRECOVER
Questa funzionalità di RMAN è una vera procedura di recupero da una corruzione di blocchi in Oracle. Credo che si tratti di una funzionalità disponibile solo con Enterprise Edition e permette di ripristinare un blocco corretto, lo fa utilizzando i backup di RMAN.

Nei test da me fatti ho riscontrato delle difficoltà, in quanto dopo aver utilizzato le procedure di DBMS_REPAIR non riuscivo a recuperare i blocchi tramite BLOCKRECOVER. Nell’output di RMAN compariva il messaggio:
some blocks not recovered: See trace file for details

La cosa che mi ha lasciato perplesso è che droppando l’oggetto coinvolto nella corruzione e ricreandolo durante gli insert mi ritrovavo con l’errore di blocco corrotto:

SQL> DROP TABLE TESTBR PURGE;
create table testbr (
 aid number,
 descriz  varchar2(100),
 b number,
 X NUMBER,
 c varchar2(100),

Table dropped.

SQL>   2    3    4    5    6    7   d number,
  8   e date
  9  );

Table created.

SQL> SQL> begin
  2   for i in 1000000..1000154 loop
  3    insert into testbr values (i,rpad(i,100,'P'),i,999,rpad(i,100,'H'),i,sysdate);
  4   end loop;
  5  end;
  6  /
begin
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 4, block # 104294)
ORA-01110: data file 4: '/opt/oracle/oradata/test102/users01.dbf'
ORA-06512: at line 3

Cosa che a rigore non dovrebbe succedere perchè Oracle dovrebbe riformattare l’oggetto.

ANALYZE TABLE … VALIDATE STRUCTURE

Un altro strumento per fare controlli sulla consistenza logica di una tabella è il comando ANALYZE TABLE … VALIDATE STRUCTURE che fa controlli analoghi a quelli della procedura DBMS_REPAIR.CHECK_OBJECT

Conclusioni

In questo post ho fatto una rassegna non esaustiva e non dettagliata dei metodi di analisi delle corruzioni su un database Oracle. La conclusione dei miei test rafforza quello in cui già credevo: FARE SEMBRE DEI BACKUP CON RMAN. Anche non disponendo della Enterprise Edition e quindi di BLOCKRECOVER e sempre possibile ripristinare un intero datafile senza perdere un solo record. Chiaramente BLOCKRECOVER è molto potente perchè permette di fare la riparazione molto più velocemente. In ogni caso la mancanza di un backup comporta perdita di dati, compreso l’uso del package DBMS_REPAIR.

Nelle mie politiche di backup vi è anche l’export che assieme ad RMAN fa ulteriori controlli di integrità dei dati, per cui eventuali problemi emergono subito al verificarsi.

Riferimenti:

– Da metalink, necessitano di account:

6 commenti »

RSS feed for comments on this post. TrackBack URI

  1. […] Pubblicato il Giovedì 29 Maggio 2008 di cristiancudizio Questo post è una continuazione del precedente. Nel mio ambiente di test su cui ho fatto le prove di recovery si è presentato un caso reale di […]

  2. Ciao,
    sono l’ICT manager di una società che usa Oracle 10g R2.
    Abbiamo migrato a Novembre dalla vecchia 7.3.4 senza particolari problemi con un export ed un import.
    Ogni tanto capita di riscontrare quelli che tu definisci “corruzione applicativa”, cioè record padre senza figli che, in teoria, l’applicativo non consentirebbe.
    Noi sviluppiamo con un tool che si chiama Uniface in architettura client-server.
    Sul client gira la form applicativa che, tramite un agente sul server (sempre di Uniface), esegue il comando “store” che si occupa di scrivere, loccare e unloccare, committare secondo quanto richiesto.
    Oggi, dopo dieci anni che funziona egregiamente, l’applicativo di fatturazione s’è perso il dettaglio di un’ottantina di note credito e non abbiamo idea di che cosa cercare.
    Problemi simili potrebbero essere a carico del database.
    Ciao e grazie.

    Massimo.

  3. Ciao Massimo,
    il problema che tu riporti è veramente curioso, per non dire bizzarro oltre che chiaramente grave. Devo supporre che sul database non siano definiti vincoli di integrità referenziale (foreign key), cosa che peraltro accade anche sui nostri database. Sappiamo che la quasi unanimità degli esperti pone l’utilizzo dei vincoli fra le cose da cui non si può prescindere per un buon progetto. Ciò nonostante noi, evidentemente grazie alla bravura dei nostri programmatori, non abbiamo vai avuto problemi simili. Nel tuo caso, chiaramente se l’applicazione ha sempre funzionato non si capisce perché non dovrebbe funzionare più. L’attivazione dei vincoli potrebbe aiutarvi a individuare il problema che ad esempio potrebbe essere causato dai driver. E’ l’unica cosa che mi viene in mente, visto che la versione 10gR2 mi sembra abbastanza stabile e robusta.

  4. Ciao Cristian.
    E’ esatto, nel DB non sono stati impostati vincoli per il semplice fatto che lo strumento che abbiamo permette di impostarli a livello sviluppo del software ed è lì che definiamo relazioni padre-figlio.
    Ed è vero anche per noi che ci affidiamo alla bravura dei nostri softwaristi con riscontri positivi.
    E’ la prima volta in dieci anni, da quando usiamo sia Oracle che Uniface, che capita una cosa del genere.
    Potrebbe essere anche un baco dell’agente Uniface montato sul DB server che interfaccia le richieste dei clients ma, esendoci accorti del fatto a posteriori, è praticamente impossibile indagare in merito.
    Conosci qualche buon libro che possimo usare per approfondire Oracel senza doversi spazzolare tutti i manuali?
    Al momento abbiamo la gestione del DB all’esterno.
    Ciao e grazie.

    Massimo.

  5. Se vai alla sezione libri di questo blog, il primo è quello di Thomas Kyte, una bibbia, un “must have”, un concentrato di utili suggerimenti e informazioni. Non è male neanche il terzo, quello di Sam Alapati che lo giudico un buon riassunto dei manuali. Infine, per fermarmi a tre c’è Kevin Loney e Bob Bryla: “Oracle Database 10g DBA Handbook” (il numero 7).

  6. […] passati quasi quattro anni da quando ho scritto questo post e questo post sulla corruzione dei blocchi in Oracle, da allora non mi sono capitati molti di […]


Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

Crea un sito o un blog gratuitamente presso WordPress.com.
Entries e commenti feeds.

%d blogger cliccano Mi Piace per questo: