Ripristino da una corruzione dello schema mysql
Anche se il formato della tabella di MySQL è molto affidabile (tutte le modifiche a una tabella fatta da un’istruzione SQL sono scritti prima l’istruzione restituisce), è ancora possibile ottenere tabelle danneggiate se uno qualsiasi dei seguenti eventi:
- Il processo mysqld viene fermato nel bel mezzo di una scrittura nel DB.
- Un blocco improvviso dovuto allo spegnimento del computer o a guasti hardware.
- Si sta utilizzando un programma esterno (come myisamchk) per modificare una tabella che viene modificata dal server allo stesso tempo. Può succedere che importando un dump esportato di MySQL, lo schema mysql si corrompa in modo anche non evidente al momento.
Questo evento può essere scoperto anche a distanza di giorni se la corruzione avviene in parti non vitali del database.
Un effetto che si può addebitare ad una corruzione del database di MySQL è l’impossibilità di fare un grant dei privilegi anche con l’utente root con tutti i flag abilitati per farlo.
Quando si prova ad eseguire GRANT ALL ON *.* TO ‘myuser’@’localhost’;
Ad esempio viene restituito il seguente messaggio: ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: YES)
Sfortunatamente strumenti come mysqlrepair o mysql_install_db non riescono a sistemare il problema.
[ERROR] Column count of mysql.proc is wrong. Expected 20, found 16. The table is probably corrupted
A questo punto ci sono solo due vie particabili: la prima prevede la disinstallazione di MySQL e reinstallazione con la ricreazione dello schema mysql. La seconda l’eliminazione dei file dello schema e la riconfigurazione del database.
La prima via è più lunga e comporta problemi in fase di reinstallazione delle dipendenze. Opteremo per la seconda strada.
Fare un dump del database con il comando mysqldump.
Accertarsi di aver copiato i dati di mysql.user e mysql.db che contengono rispettivamente i nomi degli utenti e i privilegi di questi nei vari database.
Si può usare un tool come phpMyAdmin e ricavare qualcosa come questo:
INSERT INTO `db` (`Host`, `Db`, `User`, `Select_priv`, `Insert_priv`, `Update_priv`, `Delete_priv`, `Create_priv`, `Drop_priv`, `Grant_priv`, `References_priv`, `Index_priv`, `Alter_priv`, `Create_tmp_table_priv`, `Lock_tables_priv`, `Create_view_priv`, `Show_view_priv`, `Create_routine_priv`, `Alter_routine_priv`, `Execute_priv`) VALUES
(‘localhost’, ‘DATABASE’, ‘UTENTE’, ‘Y’, ‘Y’, ‘Y’, ‘Y’, ‘Y’, ‘Y’, ‘N’, ‘N’, ‘Y’, ‘Y’, ‘N’, ‘N’, ‘N’, ‘N’, ‘N’, ‘N’, ‘N’),
Spegnere il database con il comando:
#service mysql stop
#/etc/init.d/mysql stop
oppure con:
# mysqladmin shutdown -u root -p
Fare una copia dei file contenuti nella cartella /var/lib/mysql che sono i file che contengono tutti gli schemi di MySQL.
# mkdir /root/cpdb/
# cp -r /var/lib/mysql/ /root/cpdb/
Cancellare definitivamente lo schema mysql col comando:
# rm -r /var/lib/mysql/mysql
Ora lanciare il comando
/usr/bin/mysql_secure_installation
Nota: l’esecuzione di TUTTE LE PARTI di questo script è consigliata per tutti
i server MySQL in uso in produzione! SI PREGA DI LEGGERE ATTENTAMENTE OGNI PASSO!
Per collegarsi a MySQL in modo sicuro, è necessario inserire la
password per l’utente root. Se MySQL è stato appena installato, e
non è stata ancora impostata la password di root, la password sarà vuota,
così si deve solo premere invio.
Enter current password for root (enter for none):
La password dell’utente root è stata annullata (vuota).
Ricordarsi di inserire una password complicata per l’utente root:
Re-enter new password:
Reloading privilege tables..
… Success!
Per impostazione predefinita, l’installazione di MySQL ha un utente anonimo, che permette a chiunque
per accedere a MySQL. Questo è inteso solo per test, è necessario rimuoverlo in un
ambiente di produzione.
Remove anonymous users? [Y/n] Y
… Success!
Normalmente, all”utente root è consentito connettersi solo da ‘localhost’. Questo
assicura che non ci si possa collegare via rete direttamente usando l’account root.
Disallow root login remotely? [Y/n] Y
… Success!
Per impostazione predefinita, MySQL viene installato con un database chiamato ‘test’ che chiunque può
usare. Dovrebbe essere rimosso in un ambiente di produzione.
Remove test database and access to it? [Y/n] Y
– Dropping test database…
… Success!
– Removing privileges on test database…
… Success!
Il ricaricamento delle tabelle dei privilegi farà in modo che tutte le modifiche fatte finora
avranno effetto immediato.
Reload privilege tables now? [Y/n] Y
… Success!
Cleaning up…
Tutto fatto! Completando tutti i passaggi di cui sopra, l’installazione di MySQL
dovrebbe essere sicura.
Thanks for using MySQL!
A questo punto, non serve importare i database già creati però occorre inserire i dati salvati da mysql.user e mysql.db o in alternativa ricreare gli utenti e assegnare loro i vari privilegi di accesso ai database.