Ho accidentalmente lasciato cadere un database MySQL sul mio server. Esistono modi per ripristinare un database eliminato?
Ho accidentalmente lasciato cadere un database MySQL sul mio server. Esistono modi per ripristinare un database eliminato?
Risposte:
Se agisci velocemente, c'è un'alta probabilità di riavere il tuo database. La possibilità è maggiore per InnoDB, per MyISAM è diverso da zero, ma vicino.
La questione è quando MySQL esegue DROP TABLE o DROP DATABASE (che è essenzialmente lo stesso) InnoDB non cancella i dati. Le pagine con i dati sono ancora sul disco.
A seconda dell'impostazione innodb_file_per_table, il processo di ripristino differisce. Se innodb_file_per_table è OFF (impostazione predefinita fino a 5.5), la tabella eliminata rimane in ibdata1. Se innodb_file_per_table è ON (impostazione predefinita a partire da 5.5), la tabella eliminata era nel rispettivo file .ibd. MySQL rimuove questo file quando elimina la tabella.
La prima cosa da fare è interrompere qualsiasi possibile scrittura in modo che la tabella non venga sovrascritta. Se innodb_file_per_table è OFF è sufficiente fermare MySQL (uccidere -9 è ancora meglio, ma assicurati di uccidere prima safe_mysqld). Se innodb_file_per_table è ON, allora umount partition in cui MySQL memorizza i suoi dati. Se il datadir si trova sulla partizione di root, consiglio di chiudere il server o almeno di prendere un'immagine del disco. Consentitemi di ripetere, l'obiettivo è impedire la sovrascrittura della tabella abbandonata da MySQL o dal sistema operativo.
Esiste uno strumento che consente di lavorare con pagine InnoDB a basso livello, toolkit di recupero dati TwinDB . Lo userò per illustrare il recupero undrop.
Devi prendere il supporto con la tabella rilasciata (ibdata1 o l'immagine del disco) e trovare pagine InnoDB su di esso. lo strumento stream_parser dal toolkit lo fa.
./stream_parser -f /path/to/disk/image
Scansionerà il file, troverà le pagine di InnoDB e le ordinerà per tipo e index_id. index_id è un identificatore che InnoDB utilizza per fare riferimento a un indice. Una tabella è memorizzata nell'indice PRIMARY. Per trovare quale index_id è la tua tabella eliminata devi recuperare il dizionario InnoDB .
Il dizionario InnoDB è memorizzato nel file ibdat1. Devi scansionare il file ibdata1 come sopra:
./stream_parser -f /var/lib/mysql/ibdata1
Ora devi ottenere i record dalle tabelle del dizionario InnoDB SYS_TABLES e SYS_INDEXES (supponiamo che la tua tabella sia sakila.actor):
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql | grep sakila/actor
000000000B28 2A000001430D4D SYS_TABLES "sakila/actor" 158 4 1 0 0 "" 0
158 è table_id, ricordalo.
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql | grep 158
000000000B28 2A000001430BCA SYS_INDEXES 158 376 "PRIMARY" 1 3 0 4294967295
000000000B28 2A000001430C3C SYS_INDEXES 158 377 "idx\_actor\_last\_name" 1 0 0 4294967295
Quindi, index_id della tabella eliminata (sakila.actor) è 376.
Ora è possibile recuperare i record della tabella eliminata da InnoDB index_id 376. È necessario disporre della struttura della tabella eliminata, esattamente l'istruzione CREATE TABLE con cui è stata creata la tabella. Dove puoi trovarlo? Dal vecchio backup o da altrove. È anche possibile recuperare la struttura dal dizionario InnoDB, ma non la tratterò in questa risposta. Supponiamo che tu ce l'abbia.
./c_parser -6f pages-ibdata1/FIL_PAGE_INDEX/0000000000000376.page -t actor.sql > dump.tsv 2> load_cmd.sql
c_parser restituisce i record come dump separato da tabulazioni a stdout. Il dump può essere caricato con il comando LOAD DATA. c_parser lo stampa su stderr.
Vedi maggiori dettagli nei post:
Non c'è modo semplice di spezzartelo. Non importa se hai lasciato cadere un db tramite phpmyadmin o dalla riga di comando. È andato.
L'errore umano è una delle ragioni per avere un buon regime di backup.
Non sono religioso ma dirò una preghiera sperando che non fosse niente di troppo importante.
Dipende dalla tua configurazione. È possibile ripristinare se si è configurato correttamente il sistema. Se si dispone di un backup, è possibile ripristinarlo. e quindi applicare i registri binari fino al punto appena prima di eliminare la tabella.
http://dev.mysql.com/doc/refman/5.5/en/mysqlbinlog.html
Ti suggerisco di farlo su un altro server, una volta ripristinata la tabella puoi usare mysqldump per estrarla e reimportarla sul tuo server di produzione. Questo non sarà un ripristino rapido, ma è possibile recuperare i dati.
Se non sai cosa stai facendo, suggerirei di aprire un contratto di supporto con una delle società di consulenza mysql (pythian, percona, palamino sono probabilmente le migliori) e chiederle di aiutarti in questo.
Vi auguro buona fortuna