Guida al ripristino di InterBase e Firebird
NOTICE: Questo documento è il capitolo del libro “The InterBase World” scritto da Alexey Kovyazin e Serg Vostrikov.
Il capitolo del libro “The InterBase World” dedicato alla riparazione dei database.
1. La storia di questa guida
Il libro russo “The InterBase World” è stato pubblicato nel settembre 2002.
La sua tiratura era di 3000 copie. Dopo 3 mesi è andato esaurito e una seconda edizione migliorata è stata pubblicata nell’aprile 2003 con una tiratura di 5000 copie.
Ora è in cima nelle più grandi librerie online russe e intendiamo che si esaurisca molto presto.
Gli autori del libro sono Alexey Kovyazin, sviluppatore di IBSurgeon e
noto specialista russo di InterBase, e Serg Vostrikov, CEO della società Devrace
È una cosa divertente, non è stato pubblicato un solo libro dedicato a InterBase in inglese!
Migliaia e migliaia di sviluppatori usano InterBase e Firebird, discutono
l’argomento in varie conferenze (guarda qui: Links).
La comunità degli sviluppatori InterBase conta in media decine di migliaia di
persone. La forte richiesta di libri su InterBase in vari paesi dimostra che la comunità InterBase è davvero grande.
Possiamo scommettere una cassa di birra sul fatto che un’edizione di 10000 copie verrebbe spazzata via da Amazon.com in un mese. Ma le persone nelle case editrici
“sanno tutto” e sono sicure che nessuno compri un libro su InterBase. È un vero peccato.
Qui vorremmo offrirti la bozza di un capitolo di questo libro dedicato al recupero dei database InterBase/Firebird.
2. Come recuperare un database InterBase/Firebird
2.1. Panoramica delle principali cause di corruzione del database
Purtroppo c’è sempre la probabilità che qualsiasi archivio di informazioni venga
corrotto e che alcune informazioni vengano perse. Il database non fa eccezione a questa regola. In questo capitolo considereremo le cause principali che portano alla corruzione del database InterBase, alcuni metodi di riparazione dei database e di estrazione delle informazioni da essi. Inoltre conosceremo le raccomandazioni e le precauzioni che minimizzeranno la probabilità di perdita di informazioni dal database.
Prima di tutto, se parliamo di riparazione del database, dovremmo chiarire il concetto di “corruzione del database”. Un database è solitamente chiamato danneggiato se durante il tentativo di estrarre o modificare alcune informazioni compaiono errori e/o le informazioni estratte risultano perse, incomplete o del tutto errate. Ci sono casi in cui le corruzioni del database sono nascoste e vengono scoperte solo testando con strumenti speciali, ma ci sono anche corruzioni reali del database quando è impossibile connettersi al database, quando i programmi-client configurati mostrano errori strani (quando non sono state eseguite manipolazioni con il database), o quando è impossibile ripristinare il database da una copia di backup.
2.2. Le principali cause di corruzione del database sono:
- Terminazione anomala del computer server, specialmente interruzione dell’alimentazione elettrica. Per l’industria IT è una vera piaga ed è per questo che speriamo non ci sia bisogno di ricordarti ancora una volta la necessità di avere una fonte di alimentazione ininterrotta sul server.
- Difetti e guasti del computer server, specialmente HDD (hard disk drive), controller del disco, memoria principale del computer e memoria cache dei controller RAID.
- Una stringa di connessione non corretta con un database multi-client di uno o più utenti (nelle versioni precedenti alla 6.x). Quando ci si connette tramite TCP/IP, il percorso al database deve indicare nome server: unità:/percorso/nomedatabase /per server su piattaforma UNIX nomeserver: /percorso/nomedatabase /, secondo il protocollo NETBEUI \\nomeserver\unità:\percorso\nomedatabase. Anche quando ci si connette al database dal computer su cui il database si trova e il server è in esecuzione, si dovrebbe usare la stessa riga rinominando nomeserver con localhost. Non si può usare un’unità mappata nella riga di connessione. Se infrangi una di queste regole, il server considera che sta lavorando con database diversi e la corruzione del database è garantita.
- Copia di file o altro accesso ai file del database quando il server è in esecuzione. L’esecuzione del comando “shut-down” o la disconnessione degli utenti nel modo usuale non è una garanzia che il server non stia facendo nulla con il database, se l’intervallo di sweep non è impostato su “0”, può essere eseguita la raccolta dei rifiuti (garbage collection). Generalmente la raccolta dei rifiuti viene eseguita immediatamente dopo che l’ultimo utente si disconnette dal database. Di solito richiede alcuni secondi, ma se prima sono state committate molte operazioni DELETE o UPDATE, il processo può essere più lungo.
- Utilizzo di versioni instabili del server InterBase 5.1-5.5. La società Borland ha ufficialmente ammesso che c’erano diversi errori in questi server e un aggiornamento stabile 5.6 è stato rimosso solo dopo l’uscita di InterBase 6 certificato in modalità free-running per tutti i clienti dei server 5.1-5.5 sul suo sito.
- Superamento del limite di dimensione del file di database (non del database!). Per le versioni pre-InterBase 6 e alcune beta di InterBase 6 il limite del file di database è 4Gb, per InterBase 6.5 e tutte le versioni di Firebird (1.0, 1.5, 2.0, 2.1) - 32Tb. Quando la dimensione del database si avvicina al valore limite, deve essere creato un file aggiuntivo.
- Esaurimento dello spazio libero su disco quando si lavora con il database.
- Per i server Borland InterBase versioni inferiori a 6.0.1.6 - superamento del limite al numero di generatori secondo quanto definito da Borland InterBase R & D nel seguente modo (guarda tabella 1).
| Versione | Page size=1024 | Page size=2048 | Page size=4096 | Page size=8192 |
| Pre 6 | 248 | 504 | 1016 | 2040 |
| 6.0.x | 124 | 257 | 508 | 102 |
Tabella 1: Numero critico di generatori nelle prime versioni di InterBase
• Per tutti i server Borland InterBase - superamento del numero consentito di
transazioni senza eseguire backup/restore. Si può conoscere il numero di
transazioni avvenute nel database dal momento dell’ultima creazione invocando l’utilità gstat con la chiave - h - il parametro NEXT TRANSACTION ID sarà la
quantità desiderata di transazioni. Secondo Ann W. Harrison il numero critico di
transazioni dipende dalla dimensione della pagina e ha i seguenti valori (guarda tabella 2):
| Dimensione pagina database | Numero critico di transazioni |
| 1024 byte | 131 596 287 |
| 2048 byte | 265 814 016 |
| 4096 byte | 534 249 472 |
| 8192 byte | 1 071 120 384 |
Tabella 2: Numero critico di transazioni nei server Borland InterBase
I vincoli dei server Borland InterBase elencati sopra non si applicano ai
server Firebird tranne che per le primissime versioni 0.x., la cui esistenza è già diventata storia. Se usi la versione finale Firebird 1.0 o InterBase 6.5-7.x, non dovresti preoccuparti dei punti 5, 6, 8 e 9 e dovresti concentrare i tuoi sforzi su altre cause. Ora considereremo le più frequenti di esse in dettaglio.
2.3. Interruzione dell’alimentazione elettrica
Quando si spegne l’alimentazione sul server, tutte le attività di elaborazione dei dati vengono
interrotte nei punti più inaspettati e (secondo la legge di Murphy) pericolosi. Come risultato, le informazioni nel database possono essere distorte o perse. Il caso più semplice è quando tutti i dati non committati dalle applicazioni client vengono persi a seguito dello spegnimento di emergenza del server. Dopo il riavvio post-interruzione, il server analizza i dati, nota transazioni incomplete non relative a nessun client e annulla tutte le modifiche effettuate nell’ambito di queste transazioni “morte”. In realtà tale comportamento è normale e previsto fin dall’inizio dagli sviluppatori di InterBase.
Tuttavia l’interruzione dell’alimentazione non è sempre seguita solo da perdite così insignificanti. Se il server stava eseguendo l’estensione del database al momento dell’interruzione dell’alimentazione, c’è un’alta probabilità di avere pagine orfane nel file di database (pagine fisicamente allocate e registrate sulla pagina di inventario delle pagine (PIP), la cui scrittura dei dati è impossibile). Se vuoi saperne di più sulle pagine orfane guarda il capitolo «La struttura del database InterBase».
Solo lo strumento di riparazione e modifica gfix (lo considereremo sotto) è in grado di combattere le pagine orfane nel file di database. In realtà le pagine orfane portano a un inutile dispendio di spazio su disco e come tali non sono la causa di perdita di dati o corruzione.
La perdita di alimentazione porta a danni più gravi. Per esempio, dopo lo spegnimento dell’alimentazione e il riavvio, una grande quantità di dati, inclusi quelli committati, può essere persa (dopo l’aggiunta o la modifica dei quali è stato eseguito il comando «commit transaction»). Ciò accade perché i dati confermati non vengono scritti direttamente nel file di database su disco. E la cache dei file del sistema operativo (OS) viene usata per questo scopo. Il processo server ha dato il comando di scrittura dei dati all’OS. Poi l’OS ha assicurato al server che tutti i dati erano stati salvati su disco e in realtà i dati erano memorizzati nella cache dei file. L’OS non ha fretta di scaricare questi dati su disco, perché considera che c’è ancora molta memoria principale rimasta e rimanda le operazioni lente di scrittura su disco finché la memoria principale non è piena.
2.4. Scritture forzate - un’arma a doppio taglio
Per influenzare la situazione, in InterBase 6 è prevista la regolazione della modalità di scrittura dei dati. Questo parametro si chiama forced writes (FW) e ha 2 modalità - ON (sincrona) e OFF (asincrona). Le modalità FW definiscono come InterBase comunica con il disco. Se FW è attivato, viene attivata l’impostazione delle scritture sincrone su disco, quando i dati confermati vengono scritti su disco subito dopo il comando commit, il server attende il completamento della scrittura e solo allora continua l’elaborazione. Se FW è disattivato, InterBase non ha fretta di scrivere i dati su disco dopo il comando di commit della transazione e delega questo compito a un thread parallelo mentre il thread principale continua l’elaborazione dei dati senza attendere che le scritture siano completate su disco. La modalità di scrittura sincrona è una delle più prudenti e minimizza qualsiasi possibile perdita di dati, tuttavia può causare una certa perdita di prestazioni. La modalità di scrittura asincrona aumenta la probabilità di perdita di una grande quantità di dati. Per ottenere le massime prestazioni di solito si imposta la modalità FW Off. Ma come risultato di un’interruzione dell’alimentazione, molti più dati vengono persi durante le scritture asincrone che sincrone. Quando imposti la modalità di scrittura dovresti decidere se pochi punti percentuali di prestazioni sono più significativi di poche ore di lavoro se si verifica un’interruzione inaspettata dell’alimentazione.
Molto spesso gli utenti sono negligenti con InterBase. Le piccole organizzazioni risparmiano su qualsiasi sciocchezza, spesso sul computer-server dove sono installati sia il server DBMS che diversi programmi server (e non solo server). Se si bloccano, le persone pensando per poco tempo premono RESET (succede diverse volte al giorno). Sebbene InterBase sia molto stabile a tali attività rispetto ad altri DBMS e permetta di iniziare a lavorare con il database subito dopo il riavvio di emergenza, tale uso non è desiderabile. Il numero di pagine orfane aumenta e i dati perdono connessioni tra loro come risultato di riavvii errati.
Può continuare per molto tempo, ma prima o poi finirà. Quando compaiono pagine danneggiate tra le pagine PIP o le pagine dei generatori o se la pagina di intestazione del database è corrotta, il database potrebbe non aprirsi mai più e diventare un grande pezzo di dati separati da cui non si può estrarre un solo byte di informazioni utili.
2.5. Corruzione del disco rigido
Le corruzioni del disco rigido portano alla perdita di importanti pagine di sistema del database e/o alla corruzione dei collegamenti tra le pagine rimanenti. Tali corruzioni sono uno dei casi più difficili, perché quasi sempre richiedono un intervento a basso livello per ripristinare il database.
2.6. Errori di progettazione del database
È necessario che tu conosca alcuni errori commessi dagli sviluppatori di database
che possono portare all’impossibilità di recuperare il database da una copia di backup (file *.gbk creati dal programma gbak). Prima di tutto questo è un uso negligente dei vincoli a livello di database. Un esempio tipico sono i vincoli NOT NULL. Supponiamo di avere una tabella piena di un certo numero di record. Ora aggiungeremo a questa tabella usando il comando ALTER TABLE un’altra colonna e indicheremo che non deve contenere valori non definiti NULL. Qualcosa del genere:
ALTER TABLE sometable Field/INTEGER NOT NULL
E in questo caso non ci sarà alcun errore del server come ci si potrebbe aspettare. Questa modifica dei metadati verrà committata e non riceveremo alcun messaggio di errore o avviso, il che crea un’illusione di normalità di questa situazione.
Tuttavia, se eseguiamo il backup del database e proviamo a ripristinarlo da una copia di backup, riceveremo un messaggio di errore nella fase di ripristino (perché i valori Null vengono inseriti nella colonna che ha il vincolo NOT NULL, e il processo di ripristino verrà interrotto. (Nota importante fornita da Craig Stuntz - con la versione InterBase 7.1 i vincoli vengono ignorati per impostazione predefinita durante il ripristino (questo può essere controllato tramite un’opzione della riga di comando) e quasi qualsiasi backup non corrotto può essere ripristinato. È sempre una buona idea eseguire un ripristino di prova dopo aver effettuato un backup, ma questo problema dovrebbe praticamente scomparire nella versione 7.1.) Questa copia di backup non può essere ripristinata. Se il ripristino è stato diretto a un file con lo stesso nome del database esistente (durante il ripristino il file di lavoro del database esistente veniva sovrascritto) perderemo tutte le informazioni.
Ciò è collegato al fatto che i vincoli NOT NULL sono implementati da trigger di sistema che controllano solo i dati in arrivo. Durante il ripristino, i dati dalla copia di backup vengono inseriti nelle tabelle vuote appena create - qui possiamo trovare NULL inammissibili nella colonna con il vincolo NOT NULL.
Alcuni sviluppatori considerano questo comportamento di InterBase errato, ma altri non saranno in grado di aggiungere un campo con la restrizione NOT NULL alla tabella del database.
Una questione sul valore predefinito richiesto e sul suo riempimento al momento della creazione è stata ampiamente discussa dagli architetti di Firebird, ma non è stata accettata perché il programmatore ovviamente lo riempirà secondo un algoritmo piuttosto complicato e forse iterativo. Ma non c’è garanzia che sarà in grado di distinguere i record ignorati dall’iterazione precedente dai record non compilati o meno.
Un problema simile può essere causato da un errore di garbage collection a causa dell’impostazione di un percorso non corretto al database (causa di corruzione 3) al momento della connessione e dell’accesso ai file del database quando il server ci lavora (causa di corruzione 4) e record interamente riempiti con Null possono apparire in alcune tabelle. È molto difficile rilevare questi record, perché non corrispondono alle restrizioni di controllo dell’integrità, e l’operatore Select semplicemente non li vede, anche se entrano nella copia di backup. Se per questo motivo è impossibile ripristinare, si dovrebbe eseguire il programma gfix (vedi sotto), trovare ed eliminare questi record usando campi non indicizzati come condizioni di ricerca, quindi riprovare a fare una copia di backup e ripristinare il database da essa. In conclusione possiamo dire che c’è un gran numero di cause di corruzione del database e si dovrebbe essere sempre pronti al peggio - che il database venga danneggiato per un motivo o per l’altro. Devi anche essere pronto a ripristinare e salvare informazioni preziose. E ora considereremo le precauzioni che garantiscono la sicurezza del database InterBase, così come i metodi di riparazione dei database danneggiati.
2.7. Precauzioni contro la corruzione del database InterBase
Per prevenire la corruzione del database, si dovrebbero sempre creare copie di backup (se vuoi saperne di più sul backup, guarda il capitolo “Backup e ripristino”). È il modo più affidabile contro la corruzione del database. Solo il backup dà una garanzia al 100% della sicurezza del database. Come descritto sopra, come risultato del backup possiamo ottenere una copia inutile (una copia che non può essere ripristinata), ecco perché il ripristino di un database dalla copia non deve essere eseguito sovrascrivendo lo script e il backup deve essere fatto secondo regole precise. In primo luogo, il backup deve essere eseguito il più spesso possibile, in secondo luogo deve essere seriale e in terzo luogo, le copie di backup devono essere controllate per la capacità di ripristino.
Spesso il backup significa che è necessario fare una copia di backup abbastanza spesso, per esempio una volta ogni ventiquattro ore. Minore è il periodo di dati tra il backup del database, minori saranno i dati persi a causa di un guasto. La sequenza del backup significa che il numero di backup deve aumentare e deve essere conservato per almeno una settimana. Se c’è una possibilità, è necessario scrivere i backup su dispositivi speciali come streamer, ma se non c’è - basta copiarli su un altro computer. La storia delle copie di backup aiuterà a scoprire corruzioni nascoste e a gestire l’errore sorto molto tempo fa e manifestatosi inaspettatamente. Bisogna verificare se è possibile ripristinare il backup ricevuto senza errori o meno. Può essere controllato solo in un modo - attraverso il processo di ripristino di prova. Va detto che il processo di ripristino richiede 3 volte più tempo del backup, ed è difficile eseguire la validazione del ripristino ogni giorno per database di grandi dimensioni, perché potrebbe interrompere il lavoro degli utenti per alcune ore (la pausa notturna potrebbe non essere sufficiente).
Sarebbe meglio se le grandi organizzazioni non risparmiassero sui “fiammiferi” e lasciassero un computer per questi scopi.
In questo caso, se il server deve lavorare con un carico serio 24 ore su 24, 7 giorni su 7, possiamo usare il meccanismo SHADOW per fare snapshot dal database e ulteriori operazioni di backup dalla copia immediata. Il processo di backup e ripristino del database è descritto in dettaglio nel capitolo “Backup e ripristino”. Quando si crea un backup e poi si ripristina il database da esso, avviene la ricreazione di tutti i dati nel database. Questo processo (backup/ripristino o b/r) contribuisce alla correzione della maggior parte degli errori non fatali nel database, collegati a corruzioni del disco rigido, al rilevamento di problemi di integrità nel database, alla pulizia del database dalla spazzatura (vecchie versioni e frammenti di record, transazioni incomplete), riducendo considerevolmente le dimensioni del database.
Il b/r regolare è una garanzia della sicurezza del database InterBase. Se il database funziona, si raccomanda di eseguire il b/r ogni settimana. A dire il vero, ci sono alcune illustrazioni di database InterBase che sono stati usati intensamente per anni senza backup/ripristino.
Tuttavia, per essere al sicuro è desiderabile eseguire questa procedura, specialmente perché può essere facilmente automatizzata (guarda il capitolo “Backup”)
Se per qualche motivo è impossibile eseguire spesso backup/ripristino, allora si può usare lo strumento gfix per controllare e ripristinare il database. gfix permette di controllare e rimuovere molti errori senza b/r.
2.8. Strumento da riga di comando gfix
Lo strumento da riga di comando gfix è usato per controllare e ripristinare il database. Inoltre, gfix può anche eseguire varie attività di controllo del database: cambiare il dialetto del database, impostare e annullare la modalità “sola lettura”, impostare la dimensione della cache per un database specifico e anche alcune funzioni importanti (puoi conoscerle nella InterBase 6 Operations Guide [4.) gfix viene eseguito in modalità riga di comando e ha la seguente sintassi:
Gfix [ opzioni] nome_db
Opzioni - è un insieme di opzioni per eseguire gfix, nome_db è il nome del database su cui verranno eseguite le operazioni, definito dall’insieme di opzioni. La Tabella 3 rappresenta le opzioni di gfix relative alla riparazione del database:
| Opzione | Descrizione |
| -f[ull] | Questa opzione è usata in combinazione con -v e significa che è il momento di controllare tutti i frammenti dei record |
| -i[gnore] | L’opzione fa sì che gfix ignori gli errori di checksum al momento della validazione o della pulizia del database |
| -m[end] | Marca i record danneggiati come non disponibili, come risultato verranno eliminati durante il successivo backup/ripristino. L’opzione è usata al momento della preparazione del database corrotto al b/r. |
| -n[o_update] | L’opzione è usata in combinazione con -v per la validazione del database in sola lettura senza correggere le corruzioni |
| -pas[sword] | L’opzione permette di impostare la password quando ci si connette al database. (Nota che è un errore nella documentazione InterBase -pa[ssword], ma il collegamento “-pa” non funzionerà - usa “-pas”) |
| -user | L’opzione permette di impostare il nome utente per la connessione al database |
| -v[alidate] | L’opzione imposta la validazione del database nel modo in cui vengono scoperti gli errori |
| -m[ode] | L’opzione imposta la modalità di scrittura per il database - sola lettura o lettura/scrittura. Questo parametro può accettare 2 valori - read write o read only. |
| -w[rite] {sync | async} | Opzione che attiva e disattiva la modalità sincrona/asincrona di scritture forzate al database. sync - per attivare le scritture sincrone (FW ON); async - per attivare le scritture asincrone (FW OFF); |
Tabella 1: Opzioni dello strumento gfix per il ripristino del database
Ci sono alcuni esempi tipici di utilizzo di gfix:
gfix -w sync -user SYSDBA -pass masterkey firstbase.gdb
In questo esempio impostiamo per il nostro database di test firstbase.gdb la modalità di scrittura sincrona (FW ON). (Ovviamente, è utile prima che si verifichi la corruzione). E sotto c’è il primo comando che dovresti usare per controllare il database dopo che si verifica la corruzione:
gfix -v -full -user SYSDBA -pass masterkey firstbase.gdb
In questo esempio iniziamo il controllo del nostro database di test (opzione -v) e indichiamo che anche i frammenti dei record devono essere controllati (opzione -full). Naturalmente, è più conveniente impostare varie opzioni per il processo di controllo e ripristino tramite qualsiasi GUI, ma considereremo le funzioni di recupero del database usando strumenti da riga di comando. Questi strumenti sono inclusi in InterBase e puoi essere sicuro che il loro comportamento sarà lo stesso su tutti i sistemi operativi che eseguono InterBase. È molto importante che siano sempre a portata di mano.
Inoltre, gli strumenti esistenti che permettono di eseguire l’amministrazione del database da un computer client usano Services API per questo, che non è supportata dall’architettura Classic del server InterBase. Ciò significa che puoi usare prodotti di terze parti con l’architettura del server SuperServer.
2.9. La riparazione del database corrotto
Supponiamo che ci siano alcuni errori nel nostro database. In primo luogo, dobbiamo verificare l’esistenza di questi errori; in secondo luogo, dobbiamo cercare di correggere questi errori. Dovresti seguire le seguenti istruzioni.
Dovresti fermare il server InterBase se è ancora in funzione e fare una copia del file o dei file del database. Tutte le attività di ripristino dovrebbero essere eseguite solo con la copia del database, perché il metodo scelto potrebbe portare a un risultato sfortunato, e dovrai riavviare la procedura di ripristino (da un punto di partenza). Dopo aver creato una copia, eseguiremo la validazione completa del database (controllo dei frammenti dei record).
Dovremmo eseguire il seguente comando per questo:
gfix -v - full corruptbase gdb -user SYSDBA - password
In questo caso corruptbase.gdb - è una copia del database danneggiato. Un comando controllerà il database per qualsiasi corruzione strutturale e fornirà l’elenco dei problemi irrisolti. Se vengono rilevati tali errori, dovremo eliminare i dati danneggiati e prepararci per il backup/ripristino usando il seguente comando:
gfix -mend -user SYSDBA -password your_masterkey corruptbase gdb
Dopo aver eseguito il comando, dovresti controllare se ci sono errori rimasti nel database. Devi eseguire gfix con le opzioni -v -full per questo, e quando il processo è finito, esegui il backup del database:
gbak -b -v -ig -user SYSDBA -password corruptbase.gdb corruptbase.gbk
Questo comando eseguirà il backup del database (l’opzione - b lo indica) e otterremo informazioni dettagliate sull’esecuzione del processo di backup (opzione -v). Gli errori relativi ai checksum verranno ignorati (opzione - ig). Se vuoi saperne di più sulle opzioni dello strumento da riga di comando gbak, puoi trovarle nel capitolo “Backup e ripristino”. Se ci sono alcuni errori con il backup, dovresti avviarlo in un’altra configurazione:
gbak -b -v -ig -g -user SYSDBA -password corruptbase.gdb
corruptbase.gbk
Dove l’opzione - g disattiverà la garbage collection durante il backup. Spesso aiuta a risolvere un problema con il backup.
Potrebbe anche essere possibile fare un backup del database, se prima impostiamo il database in modalità sola lettura. Questa modalità impedisce la scrittura di qualsiasi modifica al database e a volte aiuta a eseguire il backup di un database danneggiato. Per impostare il database in modalità sola lettura, dovresti usare il seguente comando: gfix -m read _only
-user SYSDBA -password masterkey Disk:\Path\file.gdb
Dopo di che, dovresti riprovare a eseguire il backup del database utilizzando i parametri indicati sopra.
Se il backup è stato eseguito con successo, dovresti ripristinare il database dalla copia di backup. Dovresti utilizzare il seguente comando:
gbak -c -user SYSDBA -password masterkey Disk:\Path\backup.gbk
Disk:\Path\newbase,gdb
Quando si ripristina il database, si potrebbero incontrare alcuni problemi, soprattutto durante la creazione degli indici. In questo caso, le opzioni -inactive e -one_at_a_time dovrebbero essere aggiunte al comando di ripristino. Queste opzioni disattivano gli indici durante la creazione dal backup del database e confermano i dati per ogni tabella.
2.10. Come si può tentare di estrarre i dati da un database corrotto
È possibile che le operazioni sopra indicate non portino al recupero del database. Ciò significa che il database è gravemente danneggiato o che non può essere ripristinato come un’unica entità, oppure che è necessario compiere un grande sforzo per il suo recupero. Ad esempio, si può eseguire una modifica dei metadati di sistema, utilizzare funzioni non documentate e così via. È un lavoro molto difficile, lungo e ingrato, con scarse possibilità di successo. E se possibile, cerca di evitarlo e usa altri metodi. Se un database danneggiato si apre e consente di eseguire operazioni di lettura e modifica su alcuni dati, dovresti sfruttare questa possibilità e salvare i dati copiandoli in un nuovo database, e “salutare per sempre” il vecchio.
Quindi, prima di trasferire i dati dal vecchio database, è necessario creare un database di destinazione. Se il database non è stato modificato per molto tempo, puoi utilizzare il vecchio backup, da cui è possibile estrarre i metadati per creare un database di destinazione. Sulla base di questi metadati, si deve creare una destinazione dati e iniziare a copiare i dati. Il compito principale è estrarre i dati da un database danneggiato. Poi dovremo allocare i dati in un nuovo database, ma non è molto difficile, anche se dovremo ricostruire la struttura del database dalla memoria. Quando si estraggono i dati dalle tabelle, dovresti utilizzare il seguente algoritmo di operazioni:
- Prima di tutto, dovresti provare a eseguire SELECT* dalla tabella N. Se va a buon fine, puoi salvare i dati ottenuti in una sorgente esterna. È meglio memorizzare i dati in uno script (quasi tutte le GUI offrono questa funzione), a meno che la tabella non contenga campi BLOB. Se ci sono campi BLOB nella tabella, i dati da essi dovrebbero essere salvati in un altro database tramite un programma client che farà da mediatore. Forse dovrai scrivere questo programma banale appositamente per il recupero dei dati.
- Se non riesci a recuperare tutti i dati, dovresti eliminare tutti gli indici e riprovare. In pratica, gli indici possono essere eliminati da tutte le tabelle fin dall’inizio del ripristino, perché non saranno più necessari. Naturalmente, se non hai una struttura di metadati uguale a quella corrotta, è necessario registrare un protocollo di tutte le operazioni che stai eseguendo con il database sorgente danneggiato.
- Se non riesci a leggere tutti i dati dalla tabella dopo aver eliminato gli indici, puoi provare a eseguire una query per intervalli sulla chiave primaria. Ciò significa selezionare un intervallo definito di dati. Ad esempio:
SELECT * FROM table N WHERE field_PK >=0 and field_PK <=10000 Field_PK
qui è una chiave primaria. InterBase ha un’organizzazione dei dati a pagine e per questo motivo la query per intervalli di valori può essere piuttosto efficace, anche se sembra una sorta di sciamanesimo. Tuttavia funziona perché possiamo escludere i dati dalla query dalle pagine danneggiate e leggere fortunatamente le altre. Puoi ricordare la nostra tesi che non esiste un ordine definito di memorizzazione dei record in SQL. In realtà, nessuno garantisce che una query non ordinata durante i riavvii restituisca i record nello stesso ordine, ma comunque i record fisici sono memorizzati all’interno del database in un ordine interno definito. È ovvio che il server non mescolerà i record solo per rispettare lo standard SQL. Puoi provare a usare questo ordine interno per estrarre i dati da un database danneggiato (se vuoi saperne di più sulle pagine dati e le loro correlazioni, consulta il capitolo “Struttura del database InterBase”).
Vitaliy Barmin, uno degli esperti sviluppatori russi di InterBase, ha riferito che in questo modo è riuscito a recuperare fino al 98% delle informazioni da un database irrecuperabile (c’erano un gran numero di pagine danneggiate). Quindi, i dati da un database danneggiato devono essere spostati in un nuovo database o in sorgenti esterne come script SQL. Quando copi i dati, presta attenzione ai valori dei generatori nel database danneggiato (devono essere salvati per riavviare un corretto funzionamento nel nuovo database. Se non hai una copia completa dei metadati, dovresti estrarre i testi delle stored procedure, dei trigger, dei vincoli e la definizione degli indici.
2.11. Ripristino di un database senza speranza
In generale, il ripristino di un database può essere molto problematico e difficile, ed è per questo che è meglio fare una copia di backup del database piuttosto che ripristinare i dati danneggiati; e qualunque cosa accada, non dovresti disperare perché una soluzione può essere trovata nelle situazioni più difficili. E ora considereremo 2 casi.
Il primo caso (un problema classico). Un backup che non può essere ripristinato a causa di valori NULL nella colonna con vincoli NOT NULL (il processo di ripristino è stato eseguito sul file di lavoro). Il file di lavoro è stato cancellato e il processo di ripristino è stato interrotto a causa di un errore. E come risultato di azioni sconsiderate abbiamo ottenuto un gran numero di dati inutili (che non possono essere ripristinati) invece della copia di backup. Ma la soluzione è stata trovata. Il programmatore è riuscito a ricordare quale tabella e quale colonna avevano vincoli NOT NULL. Il file di backup è stato caricato in un editor esadecimale. E una combinazione di byte, corrispondente alla definizione di questa colonna, è stata trovata lì tramite ricerca. Dopo innumerevoli esperimenti, è risultato che il vincolo NOT NULL aggiunge 1 da qualche parte vicino al nome della colonna. Nell’editor HEX questo “1” è stato corretto in “0” e la copia di backup è stata ripristinata. Dopo quel caso, il programmatore ha memorizzato una volta per tutte come eseguire il processo di backup e ripristino.
Il secondo caso. La situazione era catastrofica. Database corrotto nella fase di estensione a causa della mancanza di spazio su disco. Quando si aumenta la dimensione del database, il server crea una serie di pagine criticamente importanti (ad esempio, pagina di inventario delle transazioni e pagina di inventario delle pagine, pagine aggiuntive per la relazione RDB$Pages) e le scrive alla fine del database. Di conseguenza, il database non si apriva né tramite gli strumenti di amministrazione né tramite l’utility GBAK. E quando abbiamo provato a connetterci al database, appariva un messaggio di errore (“Unexpected end of file”).
Quando abbiamo eseguito l’utility gfix, accadevano cose strane: il programma lavorava in un ciclo infinito. Mentre gfix lavorava, il server scriveva errori nel log (file InterBase log) ad alta velocità (circa 100 Kb al secondo). Di conseguenza, il file di log riempiva molto rapidamente tutto lo spazio libero su disco. Abbiamo persino dovuto scrivere un programma che cancellasse questo log tramite timer. Questo processo è durato a lungo - gfix ha lavorato per più di 16 ore senza alcun risultato. Il log si riempiva di errori del seguente tipo: “Page XXX doubly allocated”. Nei sorgenti di partenza di InterBase (nel file val.#) c’è una breve descrizione di questo errore. Dice che questo errore appare quando la stessa pagina dati viene utilizzata due volte. È ovvio che questo errore è il risultato della corruzione di pagine criticamente importanti.
Di conseguenza, dopo diversi giorni di esperimenti sfortunati, i tentativi di ripristinare i dati con metodi standard sono stati abbandonati. Ed è per questo che abbiamo dovuto utilizzare un’analisi di basso livello dei dati memorizzati nel database danneggiato.
Alexander Kozelskiy, capo del dipartimento di tecnologie informatiche di East View Publications Inc, è l’autore dell’idea di come estrarre informazioni da database irrecuperabili simili.
Il metodo di ripristino che abbiamo ottenuto come risultato delle ricerche si basava sul fatto che il database ha un’organizzazione a pagine e i dati di ogni tabella sono raccolti in pagine dati. Ogni pagina dati contiene l’identificatore della tabella per cui memorizza i dati. Era particolarmente importante ripristinare i dati da diverse tabelle critiche. C’erano dati da tabelle simili, ricevuti da una vecchia copia di backup che funzionava perfettamente e poteva essere un modello. Il database-modello è stato caricato in un editor di sorgenti esadecimali e poi abbiamo cercato i modelli di quei dati che ci interessavano. Questi dati sono stati copiati in un buffer in formato esadecimale e poi i resti del database danneggiato sono stati caricati nell’editor. Una sequenza di byte corrispondente al modello è stata trovata nel database danneggiato, e la pagina è stata analizzata (su cui è stata trovata questa sequenza).
All’inizio abbiamo definito la pagina di inizio, ma non è stato difficile perché la dimensione del file del database è divisibile per la dimensione della pagina dati. Un numero di byte corrente diviso per la dimensione della pagina - 8192 byte, approssima il risultato a un intero (e ha ottenuto il numero della pagina corrente). Poi abbiamo moltiplicato il numero della pagina corrente per la dimensione della pagina e abbiamo ottenuto il numero di byte corrispondente all’inizio della pagina corrente. Dopo aver analizzato l’intestazione, abbiamo definito il tipo di pagina (per le pagine con dati il tipo è 5 - guarda il file ods.h dall’insieme dei sorgenti di partenza di InterBase e anche il capitolo “La struttura del database InterBase”) così come l’identificatore della tabella necessaria.
Poi è stato scritto un programma che analizzava l’intero database, raccoglieva tutte le pagine per la tabella necessaria in un unico pezzo e lo spostava in un file.
Quindi, quando abbiamo ottenuto i dati di cui avevamo bisogno in primo luogo, abbiamo iniziato ad analizzare il contenuto delle pagine selezionate. InterBase utilizza ampiamente la compressione dei dati per risparmiare spazio. Ad esempio, una stringa come VARCHAR contenente la stringa “ABC”, memorizza una sequenza dei seguenti valori: lunghezza della stringa (2 byte), nel nostro caso è 0003, e poi i simboli stessi e poi il checksum. Abbiamo dovuto scrivere un analizzatore di stringhe così come di altri tipi di database che convertisse i dati dal formato esadecimale in una vista ordinaria. Siamo riusciti a estrarre fino all'80% delle informazioni da diverse tabelle critiche usando un metodo “manuale” di analisi del contenuto del database. Successivamente, sulla base dell’esperienza, Oleg Kulkov e Alexey Kovyazin, uno degli autori di questo libro, hanno sviluppato l’utility InterBase Surgeon che esegue l’accesso diretto al database, bypassando il motore InterBase e permette di leggere e interpretare direttamente i dati all’interno del database InterBase in modo corretto.
Usando InterBase Surgeon, siamo riusciti a rilevare le cause della corruzione e a ripristinare fino al 90% di database assolutamente irrecuperabili che non possono essere aperti da InterBase e ripristinati con metodi standard.
Puoi scaricare questo programma dal sito ufficiale del programma www.ib-aid.com.
3. Ringraziamenti
Vorrei ringraziare tutti coloro che mi hanno aiutato a creare questa guida:
Craig Stuntz, Alexander Nevsky, Konstantin Sipachev, Tatjana Sipacheva e tutte le altre persone gentili e competenti della comunità InterBase e Firebird.
Se hai suggerimenti o domande su questo capitolo, non esitare a scrivere un’email.
© 2002 AIexey Kovyazin, Serge Vostrikov.
Copyright © 2004 IBSurgeon Team. Tutti i diritti riservati.