Linux下MySQL误操作(UPDATE、DELETE等操作没加WHERE条件)导致数据丢失,如何恢复?

我们在操作数据的时候,难免会有操作失误,那么误操作怎么将数据恢复呢?下面我们来看看,小编是基于ubuntu下测试的。

1.以下方法是通过MySQL日志文件恢复数据,那么首先就是要开启日志
登录MySQL,开始是否开启日志:

show variables like 'log_%';
+----------------+--------+
| Variable_name  | Value  |
+----------------+--------+
| log_bin        | ON     |
|......
+----------------+--------+
未开启log_bin的值是OFF,开启之后是ON
开启方法:修改/etc/mysql/my.cnf文件,添加以下代码:
[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
max_binlog_size = 100M
binlog-format = row
重启MySQL:service mysql restart

2.查看MySQL日志是否开启成功,登录MySQL随便执行一条UPDATE、DELETE误操作语句,如下


mysql> select id,username from fun_admin;
+------+------------+
| id   | username   |
+------+------------+
| 6    | lrfun.com  |
+------+------------+
mysql> update fun_admin set username='lrfun' where id=6;
mysql> select id,username from fun_admin;
+------+------------+
| id   | username   |
+------+------------+
| 6    | lrfun      |
+------+------------+


我们误操作了一条记录,将lrfun.com改成了lrfun,现在查看以下是否有新的日志文件生成

mysql> show master status; #或者show binary logs;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000005 |     1073 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

mysql-bin.000005就是新的日志文件。

3.将binlog2sql.zip(来源于网络)上传到你的服务器,解压。
安装相关程序:
root@ubuntu:~# pip install -r requirements.txt
(注:若提示pip未安装,则执行sudo apt-get install python-pip进行安装)

4.刚刚我们知道了最新的binlog文件是mysql-bin.000005,所以从这个文件开始。然后我们也知道误操作大概的时间;
root@ubuntu:~# python ~/binlog2sql/binlog2sql.py -h 127.0.0.1 -u root -p'fun123' -d cpxgj -t fun_admin --start-file='mysql-bin.000005' --start-datetime='2018-01-26 10:55:00' --stop-datetime='2018-01-26 11:00:00';
得到我们前面误操作的SQL语句
UPDATE `cpxgj`.`fun_admin` SET `username`='lrfun', `update_time`=1466217074, `code`='45VkZp', `is_delete`=1, `id`=6, `group_id`=4, `create_time`=1461210228, `avatar`='', `password`='aa6b1b76c91371dd203e25ee3d584492', `email`='2947253330@qq.com' WHERE `username`='lrfun.com' AND `update_time`=1466217074 AND `code`='45VkZp' AND `is_delete`=1 AND `id`=6 AND `group_id`=4 AND `create_time`=1461210228 AND `avatar`='' AND `password`='aa6b1b76c91371dd203e25ee3d584492' AND `email`='2947253330@qq.com' LIMIT 1; #start 613 end 1042 time 2018-01-26 10:57:01
5.我们得到了误操作SQL的准确位置在613-1042之间,再根据位置进一步过滤,使用flashback模式生成回滚SQL,检查回滚SQL是否正确
root@ubuntu:~# python ~/binlog2sql/binlog2sql.py -h 127.0.0.1 -u root -p'fun123' -d cpxgj -t fun_admin --start-file='mysql-bin.000005' --start-pos=613 --end-pos=1042 -B;
得到以下回滚SQL:
UPDATE `cpxgj`.`fun_admin` SET `username`='lrfun.com', `update_time`=1466217074, `code`='45VkZp', `is_delete`=1, `id`=6, `group_id`=4, `create_time`=1461210228, `avatar`='', `password`='aa6b1b76c91371dd203e25ee3d584492', `email`='2947253330@qq.com' WHERE `username`='lrfun' AND `update_time`=1466217074 AND `code`='45VkZp' AND `is_delete`=1 AND `id`=6 AND `group_id`=4 AND `create_time`=1461210228 AND `avatar`='' AND `password`='aa6b1b76c91371dd203e25ee3d584492' AND `email`='2947253330@qq.com' LIMIT 1; #start 613 end 1042 time 2018-01-26 10:57:01

6.确认回滚SQL正确,执行回滚语句。
root@ubuntu:~# python ~/binlog2sql/binlog2sql.py -h 127.0.0.1 -u root -p'fun123' -d cpxgj -t fun_admin --start-file='mysql-bin.000005' --start-pos=613 --end-pos=1042 -B | mysql -h 127.0.0.1 -u root -p'fun123';

7.登录MySQL,查看数据是否回滚成功。
mysql> select id,username from fun_admin;
+----+-----------+
| id | username  |
+----+-----------+
|  6 | lrfun.com |
+----+-----------+

参数注解:
MySQL连接配置
-h host; -P port; -u user; -p password

解析模式
--stop-never 持续解析binlog。可选。,默认False,同步至执行命令时最新的binlog位置。
-K, --no-primary-key 对INSERT语句去除主键。可选。默认False
-B, --flashback 生成回滚SQL,可解析大文件,不受内存限制。可选。默认False。与stop-never或no-primary-key不能同时添加。
--back-interval -B模式下,每打印一千行回滚SQL,加一句SLEEP多少秒,如不想加SLEEP,请设为0。可选。默认1.0。

解析范围控制
--start-file 起始解析文件,只需文件名,无需全路径 。必须。
--start-position/--start-pos 起始解析位置。可选。默认为start-file的起始位置。
--stop-file/--end-file 终止解析文件。可选。默认为start-file同一个文件。若解析模式为stop-never,此选项失效。
--stop-position/--end-pos 终止解析位置。可选。默认为stop-file的最末位置;若解析模式为stop-never,此选项失效。
--start-datetime 起始解析时间,格式'%Y-%m-%d %H:%M:%S'。可选。默认不过滤。
--stop-datetime 终止解析时间,格式'%Y-%m-%d %H:%M:%S'。可选。默认不过滤。

对象过滤
-d, --databases 只解析目标db的sql,多个库用空格隔开,如-d db1 db2。可选。默认为空。
-t, --tables 只解析目标table的sql,多张表用空格隔开,如-t tbl1 tbl2。可选。默认为空。
--only-dml 只解析dml,忽略ddl。可选。默认TRUE。
--sql-type 只解析指定类型,支持INSERT, UPDATE, DELETE。多个类型用空格隔开,如--sql-type INSERT DELETE。可选。默认为增删改都解析。用了此参数但没填任何类型,则三者都不解析。
详情请查看:https://github.com/danfengcao/binlog2sql


欢迎转载,原文地址:http://www.lrfun.com/html/technology/linux/2018/0126/129.html

上一篇:Nginx配置多站点
下一篇:window访问Ubuntu下的共享文件