mysql binlog 恢复指定表数据
一、登录数据库刷新binlog
1.1)查看当前的binlog
MySQL> show master status;
+---------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------------+----------+--------------+------------------+-------------------+
| test-150-bin.000003 | 2895377 | | | |
+---------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
1.2)刷新binlog
mysql> flush logs;
Query OK, 0 rows affected (0.01 sec)
1.3)确认刷新binlog成功
mysql> show master status;
+---------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------------+----------+--------------+------------------+-------------------+
| test-150-bin.000004 | 120 | | | |
+---------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
用show master status 命令查看当前的binlog已经由test-150-bin.000003变为test-150-bin.000004,
证明binlog已经刷新成功。
二、查询二进制日志位置
mysql> show variables like'log_bin%';
+---------------------------------+------------------------------------------+
| Variable_name | Value |
+---------------------------------+------------------------------------------+
| log_bin | ON |
| log_bin_basename | /db/mysql5.6/data/test-150-bin |
| log_bin_index | /db/mysql5.6/data/test-150-bin.index |
| log_bin_trust_function_creators | ON |
| log_bin_use_v1_row_events | OFF |
+---------------------------------+------------------------------------------+
三、从二进制日志中获取表被删除的pos:
mysqlbinlog /log/binlog_3308/bin.000012 -d jz_seckill | grep --ignore-case DROP -A3 -B4
----------------------------------------------------
# at 775995049
#160720 9:37:57 server id 18500 end_log_pos 775995186 Query thread_id=249201 exec_time=0 error_code=0
SET TIMESTAMP=1468978677/*!*/;
SET @@session.foreign_key_checks=1/*!*/;
DROP TABLE `t_sec_praise_record_copy` /* generated by server */
/*!*/;
# at 775995186
#160720 9:37:58 server id 18500 end_log_pos 775995224 GTID 0-18500-5952648
----------------------------------------------------
775995049这个开始drop的。
四、从binlog中获取指定数据库的改变数据
用mysqlbinlog 恢复ivr数据库在二进制日志test-150-bin.000003中的数据
这里假设从上一次mysql备份后,只有一个binlog产生:bin.000012
/usr/local/mysql_3308/bin/mysqlbinlog -d jz_seckill --stop-position=775995049 /log/binlog_3308/bin.000012 >/tmp/seckill.sql
如果从上次备份刷新binlog,到发现表被删掉的过程中产生了多个binlog。则要按照binlog产生的顺序,那
么恢复的次序应该是按照binglog的产生的序号,从小到大依次恢复。
假如从上次备份,到发现表被删除,共有两个binlog文件,分别是test-150-bin.000002,test-150-bin.000003 ,
则按照binlog序号从小到大的排列,恢复的顺序应该是:
mysqlbinlog -d jz_seckill /log/binlog_3308/bin.000011 >/tmp/seckill.sql
mysqlbinlog -d jz_seckill --stop-position=775995049 /log/binlog_3308/bin.000011 >>/tmp/seckill.sql
由于恢复的文件seckill.sql中包含了整个seckill数据库的所有表,我们只要恢复指定的表,还要对恢复出来的sql进行过滤。
[mysql@bjrac01 data]$ more recover_ivr.sql |grep --ignore-case -E 'insert|update|delete' -A2 -B2|grep testtuo
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
--
# at 122721
#140126 17:03:28 server id 150 end_log_pos 122721 CRC32 0xe0f851bb Intvar
SET INSERT_ID=4/*!*/;
#140126 17:03:28 server id 150 end_log_pos 122838 CRC32 0x9efcc7b2 Query thread_id=12578 exec_time=0 error_code=0
use `ivr`/*!*/;
SET TIMESTAMP=1390727008/*!*/;
INSERT INTO `testtuo` (`name`) VALUES ('d')
/*!*/;
# at 122838
将过滤后的结果保存为sql脚本,恢复到数据库即可。
如果单独恢复单独一个库,则可以使用:
(2)你可以通过–one-database 参数选择性的恢复单个数据库:
mysqlbinlog --stop-date='2005-04-20 9:59:59' /var/log/mysql/mysql-bin.000001 | mysql -u root -pmypwd –one-database db_test
mysqlbinlog --stop-date='2005-04-20 9:59:59' /var/log/mysql/mysql-bin.000001 | mysql -u root -pmypwd –one-database db_test