MySQL binlog相关

一、 简介

  • 二进制日志记录了数据库的所有变化,常用于复制、审计、基于时间点恢复。
  • 二进制日志=一组binlog文件+binlog index文件
  • binlog index文件每一行都包含一个binlog文件名 
  • active binlog file:当前正在写入的binlog文件
  • 基于语句的二进制日志过滤器 
在my.cnf中添加过滤选项
binlog-ignore-db 忽略指定db
binlog-do-db 仅保留该db信息

[mysqld]
binlog-ignore-db=one_db
binlog-ignore-db=two_db
或
[mysqld]
binlog-do-db=one_db
binlog-do=two_db

注意它使用current database(如use testdb;)来决定是否需要过滤语句,而不是依据表所在数据库

例:若设置binlog-ignore-db=bad,执行:
1. use bad; insert into t1 values(1);
2. use bad; insert into good.t2 values(1);
3. use bad; update good.t1,ugly.t2 set a=b;

以上三条语句都会被过滤掉不记入binlog,因为current database均为bad

二、 常用命令

#查看所有的二进制日志列表
SHOW MASTER LOGS;

#根据文件或时间点来删除二进制日志
PURGE { BINARY | MASTER } LOGS {TO 'log_name' | BEFORE datetime_expr }
#删除mysql-bin.000002之前的日志(不包括mysql-bin.000002)
PURGE BINARY LOGS TO 'mysql-bin.000002';
#删除2014-04-28 23:59:59时间点之前的日志(如果删除主库binlog,一定要注意从库读到主库的哪个binlog,不要删多了)
PURGE BINARY LOGS BEFORE '2014-04-28 23:59:59';

#删除所有的二进制日志并清空二进制日志索引文件(生产环境谨慎操作)
reset master; 

#删除slave复制所用的所有文件(生产环境谨慎操作)
reset slave;

#触发过期日志清除操作(需设置expire_logs_days参数)
flush logs

#查看二进制日志 mysql-bin.000001,从pos 32开始,偏移2行,查询10条
show binlog events in 'mysql-bin.000001' from 32 limit 2,10\G

三、 mysqlbinlog

1. 常用参数

  • --database=db_name或-d db_name:只列出指定数据库相关内容
  • --base64-output=decode-rows :将 BINLOG 语句中事件以 base-64 的编码显示,屏蔽一些二进制内容
  • -v:仅解释行信息
  • -vv:不但解释行信息,还将 SQL 列类型的注释信息也解析出来
  • -r:重定向到指定文件,与>作用相同
  • --start-position、--stop-position:按照指定位置解析binlog日志(精确),不指定--stop-positiion则一直到该日志结尾
  • --start-datetime、--stop-datetime:按照指定时间解析binlog日志(不准确),不指定--stop-datetime则一直到该日志结尾
  • -D --disable-log-bin:禁止恢复过程产生日志。指定-D时使用mysqlbinlog解析binlog时,会加上sql_log_bin=0,应用日志不会再记录二进制日志
  • --read-from-remote-server:解析远端服务器binlog
  • --raw  和--read-from-remote-server一起使用,输出原始的二进制日志格式,而不是SQL格式

2. 使用示例

  • 按时间解析
mysqlbinlog  --base64-output=decode-rows -v  --start-datetime='2018-03-18 15:46:30'  --stop-datetime='2018-03-18 15:47:40'  mysql-bin.000001 > /tmp/binlog.sql
  • 按pos解析
mysqlbinlog   --base64-output=decode-rows -v  --start-position=100049070 –-stop-position=100049079 mysql-bin.000001  > /tmp/tmp.sql
  • 远程获取binlog(阿里云和AWS RDS 都适用)
mysqlbinlog --read-from-remote-server --host='vg-*******.us-east-1.rds.amazonaws.com' --port=3306 --user root --password --raw --result-file=/tmp  mysql-bin-changelog.147158
  • 解析出来的日志是二进制的,需要再解析一下
mysqlbinlog  --base64-output=decode-rows -v -v  /tmp/mysql-bin-changelog.147158 > /tmp/mysql-bin.147158
  • 根据二进制日志恢复
mysqlbinlog mysql-bin.000009 --start-position 154 --stop-position 755 | mysql -uroot -p mytest
# 或者
mysqlbinlog --start-position=4 --stop-position=610 /var/lib/mysql/master-log.000042  > master-log.sql && source master-log.sql

 

binlog与数据恢复

0. 前提条件

基于binlog的恢复需要建立在全量备份恢复基础上(DB至少需要做过一次全备,建议安装完后先做一次)

1. 重做指定binlog内数据
mysqlbinlog binlog_files | mysql -u root -p

多个binlog还原最好使用一个连接完成,使用不同连接有时会导致不安全

例如:
[root@localhost /]# mysqlbinlog binlog.000001 | mysql -u root -p # DANGER!!
[root@localhost /]# mysqlbinlog binlog.000002 | mysql -u root -p # DANGER!!
如果第一个日志包含创建临时表语句CREATE TEMPORARY TABLE,第二个日志要使用该临时表,第一个导入binlog日志的进程退出后临时表会被删除,执行第二个日志文件要使用临时表时会因找不到而报 “unknown table.”

建议的方法

方法1:
所有二进制文件放在单个连接里
[root@localhost /]# mysqlbinlog binlog.000001 binlog.000002 | mysql -u root -p

方法2:
将所有二进制文件写在一个文件里执行
[root@localhost /]# mysqlbinlog binlog.000001 > ?/tmp/statements.sql
[root@localhost /]# mysqlbinlog binlog.000002 >> /tmp/statements.sql
[root@localhost /]# mysql -u root -p -e "source /tmp/statements.sql"

方法2需要过滤掉二进制文件里包含的GTID信息
[root@localhost /]# mysqlbinlog --skip-gtids binlog.000001 > ?/tmp/dump.sql
[root@localhost /]# mysqlbinlog --skip-gtids binlog.000002 >> /tmp/dump.sql
[root@localhost /]# mysql -u root -p -e "source /tmp/dump.sql"

 

2. 基于时间点的恢复
可以通过参数--start-datetime 和 --stop-datetime指定恢复binlog的起止时间点,时间使用DATETIME格式。


比如在时间点2005-04-20 10:00:00删除掉一个库,要恢复该时间点前的所有日志

mysqlbinlog --stop-datetime="2005-04-20 9:59:59" /usr/local/mysql/data/binlog.123456 | mysql -u root -p

也几个小时后才发现该错误,后面又有一系列的增删查改等操作,还需要恢复后续的binlog

可以指定起始时间

mysqlbinlog --start-datetime="2005-04-20 10:01:00" /usr/local/mysql/data/binlog.123456 | mysql -u root -p

如果不知道误操作的具体时间点,可以通过查看binlog内容定位

mysqlbinlog /usr/local/mysql/data/binlog.123456 > /tmp/mysql_restore.sql

3. 基于位置的恢复
可以通过参数--start-position 和 --stop-position指定恢复binlog的起止位置点

通过位置的恢复需要我们有更加精细的操作,例如在某个时间点我们执行了错误的语句,且这个时间点前后都有大并发操作,要确定破坏性sql的时间点,可以先导出大致的时间段的日志到文件以缩小查找范围,再去分析和确定

mysqlbinlog --start-datetime="2005-04-20 9:55:00" ?--stop-datetime="2005-04-20 10:05:00" /usr/local/mysql/data/binlog.123456 > /tmp/mysql_restore.sql

确定好需要跳过的位置之后,就可以进行恢复了

mysqlbinlog --stop-position=368312 /usr/local/mysql/data/binlog.123456 | mysql -u root -p
mysqlbinlog --start-position=368315 /usr/local/mysql/data/binlog.123456 | mysql -u root -p

注:mysqlbinlog工具的输出会在每条sql语句前增加 SET TIMESTAMP语句,恢复的数据及mysql日志反映当前时间。

 

参考

https://blog.csdn.net/huangliang0703/article/details/80923916

https://blog.csdn.net/JesseYoung/article/details/41211841

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hehuyi_In

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值