MySQLRecupero Dati

Ripristinare le tabelle INNODB di MySQL senza il file ibdata1

A chi usa il DBMS (DataBase Management System – Sistema di Gestione DataBase) MySQL sarà sicuramente capitato di perdere o cancellare accidentalmente il file ibdata1 contenuto nella cartella data di MySQL.

Questo file è molto importante, in quanto contiene il tablespace di sistema di tutte le tabelle di tipo INNODB. Grazie alla direttiva innodb_file_per_table è possibile memorizzare le pagine dati e indici all’esterno del file ibdata1, creando un file .ibd per ogni singola tabella, cosa peraltro consigliata in quanto il file ibdata1 tende a crescere notevolmente in termini di dimensioni.

Se dunque abbiamo la fortuna di aver effettuato tale operazione, potremo recuperare i nostri dati.

Pertanto, lo scenario dal quale è possibile ripristinare il tutto è il seguente:

  • il file ibdata1 è mancante
  • in una cartella di backup sono presenti tutti i file *.frm e *.ibd del database, nonché il file db.opt

Vediamo come procedere. Supponiamo che il vostro database si chiami nullalo e che ne abbiate una copia di backup nella cartella /backup/data/nullalo: la prima cosa da fare è creare un nuovo database con lo stesso nome in MySQL. Tale database verrà utilizzato come destinazione per il ripristino delle tabelle.

Dopo aver creato il database, è necessario ricreare le tabelle del DB danneggiato. Per fare ciò dobbiamo innanzitutto recuperare gli schemi delle tabelle a partire dai file *.frm, cosa che faremo avvalendoci di un tool della Oracle, MySQL Utilities (attualmente alla versione 1.5.6), scaricabile qui:

http://dev.mysql.com/downloads/utilities/

Una volta scaricato ed installato il tool, disponibile per tutte le piattaforme, avremo a disposizione il comando mysqlfrm, che dovremo lanciare dalla cartella contenente i file *.frm (/backup/data/nullalo nell’esempio) con la seguente sintassi:

mysqlfrm --server=root:rootpassword@localhost mydb:mytable.frm --port=3307

Spieghiamo un attimo in che modo costruire il comando: rootpassword è la vostra password dell’utente root per accedere al DBMS con tutti i privilegi, mydb è il nome del database di cui fanno parte le tabelle da ripristinare,  mytable.frm è il nome della specifica tabella di cui volete recuperare lo schema e 3307 è una porta per il server virtualmente generato dal comando (spawned server) – questa porta dev’essere diversa da quella della vostra istanza di MySQL (che è solitamente la 3306).

A questo punto il comando vi restituirà lo statement CREATE TABLE, necessario per creare la tabella, che dovrete lanciare in MySQL sul database nullalo vuoto precedentemente creato (vi consiglio di utilizzare un client come MySQL Workbench, SQirreL o HeidiSQL). Un esempio di output del comando è il seguente:

C:\backup\data\nullalo>mysqlfrm --server=root:rootpassword@localhost nullalo:user.frm --port=3307
# Source on localhost: ... connected.
# Starting the spawned server on port 3307 ... done.
# Reading .frm files
#
# Reading the user.frm file.
#
# CREATE statement for user.frm:
#
CREATE TABLE `nullalo`.`user` (
`Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
`User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '',
`Password` char(41) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '',
`Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Reload_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Shutdown_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`File_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Show_db_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Repl_client_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_tablespace_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT '',
`ssl_cipher` blob NOT NULL,
`x509_issuer` blob NOT NULL,
`x509_subject` blob NOT NULL,
`max_questions` int(11) unsigned NOT NULL DEFAULT '0',
`max_updates` int(11) unsigned NOT NULL DEFAULT '0',
`max_connections` int(11) unsigned NOT NULL DEFAULT '0',
`max_user_connections` int(11) unsigned NOT NULL DEFAULT '0',
`plugin` char(64) COLLATE utf8_bin DEFAULT '',
`authentication_string` text COLLATE utf8_bin,
`password_expired` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
PRIMARY KEY (`Host`,`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges'

#...done.

Ora avete di nuovo la vostra tabella ma senza dati, che sono invece contenuti nel file .ibd. Per ripristinare i dati eseguiremo i seguenti passi:

  1. lanciare il comando
    ALTER TABLE mydb.mytable DISCARD TABLESPACE;
  2. copiare il file mytable.ibd (mytable va ovviamente sostituito con il nome della tabella) dalla cartella di backup alla cartella del database (es. C:\MySQL_5.6.10\data\nullalo)
  3. lanciare il comando
    ALTER TABLE mydb.mytable IMPORT TABLESPACE;

A questo punto la vostra tabella è completamente ripristinata! Ripetete la procedura per tutte le altre tabelle di tipo INNODB e siete a posto, come potrete verificare lanciando una query su una qualsiasi delle tabelle ripristinate.

Articolo precedente

Come avviare Windows 8/8.1 in modalità provvisoria

Articolo successivo

IDE per sviluppatori: Codelobster PHP Edition

Fulvio Sicurezza

Fulvio Sicurezza

2 Commenti

  1. lele
    27 luglio 2016 at 14:29 — Rispondi

    Ciao,
    sto provando questa soluzione, solo che quando lancio il comando:
    mysqlfrm –server=root:rootpassword@localhost mydb:mytable.frm –port=3307

    mi restituisce:
    ERRORE: processo “3826” non trovato

    riesci ad aiutarmi pleaseee

  2. Sanam
    13 ottobre 2020 at 16:59 — Rispondi

    Thanks a lot, it helped me solve my problem.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *