背景
在进行开发的时候,本来是想删除一张废弃表,结果删表的时候没有进行对比,导致删错了数据 表,在此记录一下恢复数据的过程
一、初识binlog
1、我们知道mysq有一个专门的日志记录,叫binlog,mysql-binlog是MySQL数据库的二进制日志,用于记录用户对数据库操作的SQL语句,它记录了所有的DDL和DML语句(除了数据查询语句select),可以使用mysqlbin命令查看二进制日志的内容。运行服务器时若启用二进制日志则性能大约慢1%。但是,二进制日志的好处,即用于恢复并允许设置复制超过了这个小小的性能损失。mysqld在每个二进制日志名后面添加一个数字扩展名。每次你启动服务器或刷新日志时该数字则增加。如果当前的日志大小达到max_binlog_size,还会自动创建新的二进制日志。如果你正使用大的事务,二进制日志还会超过max_binlog_size:事务全写入一个二进制日志中,绝对不要写入不同的二进制日志中,为了能够知道还使用了哪个不同的二进制日志文件,mysqld还创建一个二进制日志索引文件,包含所有使用的二进制日志文件的文件名。默认情况下与二进制日志文件的文件名相同,扩展名为\'.index\'。你可以用--log-bin-index[=file_name]选项更改二进制日志索引文件的文件名。当mysqld在运行时,不应手动编辑该文件;如果这样做将会使mysqld变得混乱。
2、binlog使用场景
1、用于主从复制,master通过像从服务器发送binlog文件进行数据同步
2、恢复使能够最大可能地更新数据库
3、MySQL binlog格式
binlog的格式也有三种:STATEMENT、ROW、MIXED 。
1、STATMENT模式:基于SQL语句的复制(statement-based replication, SBR),每一条会修改数据的sql语句会记录到binlog中。
优点:不需要记录每一条SQL语句与每行的数据变化,这样子binlog的日志也会比较少,减少了磁盘IO,提高性能。
缺点:在某些情况下会导致master-slave中的数据不一致(如sleep()函数, last_insert_id(),以及user-defined functions(udf)等会出现问题)
2、基于行的复制(row-based replication, RBR):不记录每一条SQL语句的上下文信息,仅需记录哪条数据被修改了,修改成了什么样子了。
优点:不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。
缺点:会产生大量的日志,尤其是alter table的时候会让日志暴涨。
3、混合模式复制(mixed-based replication, MBR):以上两种模式的混合使用,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式。
4、配置binlog
在MySQL配置文件my.cnf文件中的mysqld节中添加下面的配置文件:
[mysqld]
binlog_format = mixed #设置日志格式
log-bin = /data/mysql/logs/mysql-bin.log #设置日志路径,注意路经需要mysql用户有权限写
expire_logs_days = 7#设置binlog清理时间
max_binlog_size = 100m#binlog每个日志文件大小
binlog_cache_size = 4m#binlog缓存大小
max_binlog_cache_size = 512m#最大binlog缓存大小
重启MySQL生效。
mysqld-bin.index则记录了所有的log的文件名称
binlog日志以以mysqld-bin.00000X等作为名称
5、首先进入mysql命令,查看binlog日志是否已经开启。输入命令show variables like \'log_bin\';如下图所示,如果没有开启binlog那么恭喜你,恢复数据就增加难度了。
1、show variables like \'log_bin\' 查看日志是否开启
2、show master logs; 查看日志列表
3、show master status;查看最后一个binlog日志的编号名称,及其最后一个操作事件pos结束点(Position)值。
a、查询第一个最早的binlog日志:
show binlog events\G;
b、指定查询mysql-bin.000002这个文件
show binlog events in \'mysql-bin.000002\'\G;
c、指定查询mysql-bin.000002这个文件,从pos点:624开始查起:
show binlog events in \'mysql-bin.000002\' from 624\G;
d、指定查询mysql-bin.000002这个文件,从pos点:624开始查起,查询10条(即10条语句)
show binlog events in \'mysql-bin.000002\' from 624 limit 10\G;
e、指定查询 mysql-bin.000002这个文件,从pos点:624开始查起,偏移2行(即中间跳过2个)查询10条(即10条语句)。
show binlog events in \'mysql-bin.000002\' from 624 limit 2,10\G;
6、恢复数据的方式
1、按时间点恢复
通过shell命令mysqlbinlog 查看binlog日志文件,找到需要的时间节点。然后通过以下命令
mysqlbinlog --start-datetime="2018-04-20 10:01:00" --stop-datetime="2005-04-21 10:01:00" mysql-bin.000001 | mysql -u root -pxxx database_name
--start-datetime=datetime
从二进制日志中第1个日期时间等于或晚于datetime参量的事件开始读取。datetime值相对于运行mysqlbinlog的机器上的本地时区。该值格式应符合DATETIME或TIMESTAMP数据类型。
2、按位置号恢复
通过shell命令mysqlbinlog 查看binlog日志文件,找到需要的位置节点。然后通过以下命令
mysqlbinlog --stop-position="102" --start-position="367" mysql-bin.000001 | mysql -uroot -pxxx database_name
7、其实恢复数据有很多种方式,比如平时开启备份,那么我们可以通过备份的数据进行数据库恢复,然后在通过binlog日志进行恢复。