====== Recovering a lost synchronization in mysql ====== I have a replicated mysql database and recently I've discovered that it has lost synchronization with its slave. I've decided to recover it by //the hard way//: deleting all the information in the slave and starting with a fresh copy of the master. ===== Zero step: stop the slave ===== Do this in the slave mysql> stop slave; -- disable the slow query log is necessary because -- in the event of a full restore, the logging tables -- are dropped mysql> SET GLOBAL slow_query_log=0; mysql> set global general_log=0; ===== First step: change password for all clients ===== Because this database supports various clients and its very probable that some can change something, I've decided to change all the passwords, but making a backup before. To make a backup of your actual passwords, just issue this command and copy all the results of the table: Do this in the MASTER mysql> select host, user, password from mysql.user; +------+------------+-------------------------------------------+ | host | user | password | +------+------------+-------------------------------------------+ | % | root | *xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | | % | bugtracker | *xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | | % | hg4 | *xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | | % | mc01 | *xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | | % | repl | *xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | | % | sonar | *xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | +------+------------+-------------------------------------------+ 6 rows in set (0.04 sec) Then, change the password for all your users to a new password: this will ban everyone from the server: Do this in the MASTER SET PASSWORD FOR root = password('yyyyyy'); SET PASSWORD FOR bugtracker = password('yyyyyy'); SET PASSWORD FOR hg4 = password('yyyyyy'); SET PASSWORD FOR mc01 = password('yyyyyy'); SET PASSWORD FOR repl = password('yyyyyy'); SET PASSWORD FOR sonar = password('yyyyyy'); flush privileges; After all the process, you can recover the old passwords by issuing the commands: update mysql.user set password = '*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' where user = 'root'; .... flush privileges; ==== Second step: reboot mysql server ==== Restart the server in order to make sure all the connections are released and nobody can enter again in the server (except you). In windows: Do this in the master C:\>net stop mysql The MySQL service is stopping. C:\>net start mysql The MySQL service is starting. ==== Third step: take note of the last position of the master database ==== show master status Name |Value -----------------|---------------- File |mysql-bin.000098 Position |222409 Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set| Annotate these "File" and "position": it will be needed futher. ==== Fourth step: make a full backup of your database ==== Do this in the master C:\>mysqldump --add-drop-database --add-drop-table --add-drop-trigger --all-databases -h localhost -u root -p | bzip2 -c > full-backup.sql.bz2 It is not a bad idea to double-check the copy process by calculating the md5sum: md5sum full-backup.sql.bz2 > full-backup.sql.bz2.md5 ==== Fifth step: recover in the slave database ==== Do this in the slave bzip2 -dc full-backup.sql.bz2 | mysql -h SLAVE_COMPUTER -u root -p ==== Sixth step: set the password for the repl user ==== For the replication it is a common place to have a user for this task. In my case is the ''repl'' user. Because I've changed the password in the first steps, I have to set the original password back now. Do this in the slave Do this in the slave update mysql.user set password = '*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' where user = 'repl'; ==== Sixth step: issue a change master to command in the slave ==== https://dev.mysql.com/doc/refman/5.1/en/change-master-to.html On the slave, issue the following command: Do this in the slave change master to master_host = 'MASTERHOST.example.com', master_user = 'repl', master_password = 'put-the-password-here', master_port = 3306, master_log_file = 'you have to guess the log file name that goes here from the slave', master_log_pos = ENTER THE POSITION YOU ANNOTATE IN THE LAST COMMAND; And start the slave: Do this in the slave start slave; mysql> SET GLOBAL slow_query_log=1; mysql> set global general_log=1;