mysql的binlog日志及mysql恢复误删除数据
本篇博客只作为记录自己学习mysql的binlog日志学习,文中引用均注明来源
mysql的binlog日志
二进制日志(binlog)
-
作用:
- 用于复制,在主从复制中,从库利用主库上的binlog进行重播,实现主从同步
- 用于数据库的基于时间点的还原 内容:
- 逻辑格式的日志,可以简单认为就是执行过的食物中的sql语句
- 但又不完全是sql语句这么简单,而是包括了执行的sql语句(增删改)反向的信息,也就意味着delete对应着delete本身和其反向的insert;update对应着update执行前后的基本信息;insert对应着delete和insert本身的信息
- 因此可以基于binlog做到类似于oracle的闪回功能,其实都是依赖于binlog中的日志记录 什么时候产生:
- 事务提交的时候,一次性将事务中的sql语句(一个事务可能对应多个sql语句)按照一定的格式记录到binlog中
- 这里与redo log很明显的差异就是redo log并不一定是在事务提交的时候刷新到磁盘,redo log是在事务开始之后就开始逐步写入磁盘
- 因此对于事务的提交,即便是较大的事务,提交(commit)都是很快的,但是在开启了binlog的情况下,对于较大事务的提交,可能会变得比较慢一些
- 这是因为binlog是在事务提交的时候一次性写入造成的 什么时候释放:
- binlog的默认保持时间为7天,由参数expire_logs_days配置,对于非活动的日志文件,在生成时间超过expire_logs_days配置的天数之后,会被自动删除。我的是因为改过
-
SHOW VARIABLES LIKE '%expire_logs_days%';
- 对应的物理文件:
- 配置文件的路径为log_bin_basename,binlog日志文件按照指定大小,当日志文件达到指定的最大的大小之后,进行滚动更新,生成新的日志文件。
- 对于每个binlog日志文件,通过一个统一的index文件来组织。
-
SHOW VARIABLES LIKE '%log_bin_basename%';
- 其他:
- 二进制日志的作用之一是还原数据库的,这与redo log很类似,很多人混淆过,但是两者有本质的不同
- 作用不同:redo log是保证事务的持久性的,是事务层面的,binlog作为还原的功能,是数据库层面的(当然也可以精确到事务层面的),虽然都有还原的意思,但是其保护数据的层次是不一样的。
- 内容不同:redo log是物理日志,是数据页面的修改之后的物理记录,binlog是逻辑日志,可以简单认为记录的就是sql语句
- 另外,两者日志产生的时间,可以释放的时间,在可释放的情况下清理机制,都是完全不同的。
- 恢复数据时候的效率,基于物理日志的redo log恢复数据的效率要高于语句逻辑日志的binlog
- 关于事务提交时,redo log和binlog的写入顺序,为了保证主从复制时候的主从一致(当然也包括使用binlog进行基于时间点还原的情况),是要严格一致的,MySQL通过两阶段提交过程来完成事务的一致性的,也即redo log和binlog的一致性的,理论上是先写redo log,再写binlog,两个日志都提交成功(刷入磁盘),事务才算真正的完成。
以上binlog的介绍均来源于:https://www.cnblogs.com/aozhejin/p/15849739.html,这篇文章中还介绍了其他日志,建议小伙伴们都学习下
配置binlog日志
-
查询数据库是否开启了binlog日志,on为开启
show variables like 'log_bin';
-
若未开启,请配置linux系统下的 /etc/my.cnf文件,配置后重启,切记mysql5.7的版本需要配置serverid,这个东西不配mysql就起不来了
# 开启二进制日志binlog #配置serverid(mysql5.7版本必须配置serverid) server_id=1 log-bin=mysql-bin #行格式 binlog_format=ROW #过期时间 expire_logs_days=2
-
重启后查询mysql,看看是否配置成功,并查询binlog的一些信息,例如binlog文件存储位置等
mysql> show variables like 'log_%'; +----------------------------------------+------------------------------------+ | Variable_name | Value | +----------------------------------------+------------------------------------+ | log_bin | ON | | log_bin_basename | /server/mysql/data/mysql-bin | | log_bin_index | /server/mysql/data/mysql-bin.index | | log_bin_trust_function_creators | OFF | | log_bin_use_v1_row_events | OFF | | log_builtin_as_identified_by_password | OFF | | log_error | /var/log/mysql/mysql.log | | log_error_verbosity | 3 | | log_output | FILE | | log_queries_not_using_indexes | OFF | | log_slave_updates | OFF | | log_slow_admin_statements | OFF | | log_slow_slave_statements | OFF | | log_statements_unsafe_for_binlog | ON | | log_syslog | OFF | | log_syslog_facility | daemon | | log_syslog_include_pid | ON | | log_syslog_tag | | | log_throttle_queries_not_using_indexes | 0 | | log_timestamps | UTC | | log_warnings | 2 | +----------------------------------------+------------------------------------+
-
配置成功后,会在上述查询语句中log_bin_basename路径下有类似文件,该文件则为binlog文件
-
查看指定binlog文件的内容(也看不出来什么东西,后续用mysql自带的mysqlbinlog查看)
mysql> show binlog events in 'mysql-bin.000007'; +------------------+-----+----------------+-----------+-------------+---------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+-----+----------------+-----------+-------------+---------------------------------------+ | mysql-bin.000007 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.19-log, Binlog ver: 4 | | mysql-bin.000007 | 123 | Previous_gtids | 1 | 154 | | | mysql-bin.000007 | 154 | Stop | 1 | 177 | | +------------------+-----+----------------+-----------+-------------+---------------------------------------+ 3 rows in set (0.07 sec)
-
使用mysqlbinlog查看binlog,(mysqlbinlog工具在mysql安装路径bin目录下,有的也在/usr/bin/下),如果binlog格式是行模式的,请加 -vv参数
如果mysqlbinlog与mysql命令在/usr/bin下找不到,就进入到mysql的bin目录下用 ./ 执行,可能是直接买的宝塔自动安装的mysql,
最好使用ln -s /www/server/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog 命令注册到/usr/bin下,这样后续就可以在任何目录使用了
-
基于开始/结束时间
#注:因为我的mysql binlog就是ROW格式的,所以需要添加-vv参数 # 进入到mysqlbinlog工具路径下,mysql安装路径bin目录下 或 /usr/bin/ 自己找一下看看在哪 # ./mysqlbinlog ----start-datetime='开始时间' --stop-datetime='结束时间' -vv binlog文件路径加文件名 ./mysqlbinlog --base64-output=decode-rows -v --start-datetime='2022-08-26 08:00:00' --stop-datetime='2022-08-26 23:30:40' -vv /server/mysql/data/mysql-bin.000002
-
基于pos值
# mysqlbinlog --start-position=1088 --stop-position=3111 -d 数据库名称 binlog文件 mysqlbinlog --start-position=1088 --stop-position=3111 -d yc_study /server/mysql/data/mysql-bin.000002
基于pos值进行回滚数据
-
操作数据库,查询id=1的age值
-
更改 id = 1 的age值为50
-
开始恢复数据,选择恢复数据的pos位置点
show binlog events in 'mysql-bin.000003';
-
执行binlog恢复
#指定数据库执行 mysqlbinlog --no-defaults --start-position=219 --stop-position=508 --database=yc_study /server/mysql/data/mysql-bin.000003 | mysql -uroot -p -v yc_study #不指定数据库执行 mysqlbinlog --no-defaults --start-position=219 --stop-position=508 /server/mysql/data/mysql-bin.000003 | mysql -uroot -p #需要输入数据库密码
-
查看数据库,是否恢复
-
其他binlog命令
# 筛选update命令 mysqlbinlog --no-defaults --database=yc_study mysql-bin.000003 |grep update |more # 查看文件大小 show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000002 | 4241 | | mysql-bin.000003 | 1021 | +------------------+-----------+ # 刷新binlog,开始生成新的binlog文件 flush logs;