1 前言
一般来说,在生产环境DBA都会在定期生成全量数据的备份,然后开启binlog记录增量数据。恢复的时候借助数据备份和binlog日志一般情况下是可以很大程度上复原数据,当然一般情况下开发也不会拥有删库的权限,一般都是有删除数据的权限。所以我们在遇到这种紧急情况不能慌,要赶紧去想办法补救。
2 备份
最简单,也是最实用的方式就是在我们接到,清理数据,或者是修改数据的需求时,先将数据备份,备份是王道。这样会让我们的数据恢复变得更容易。一般在企业中,DBA都会有备份脚本,他们会长期定时对数据进行备份,防止发生悲剧。
3 规范操作
- 操作前,先备份,不要怕麻烦,出错后就悔不当初了;
- 删除数据库、表时,不要直接用drop命令,而是重命名到一个专用归档库里;
- 删除数据时,不要直接用delete或truncate命令,尤其是truncate命令,目前不支持事务,无法回滚;
- 使用delete命令删除数据时,应当先开启事务,这样误操作时,还是有机会进行回滚;
- 要大批量删除数据时,可以将这些数据插入到一个新表中,确认无误后再删除。或者把要保留的数据写到新表,然后将表重命名对掉,这样需要注意的是增量数据,不要把新插入的数据丢掉;
4 基本的恢复流程
- 看看是否有办法快速补救(没有可以看下一条)
- 看看是否有定期备份,和binlog日志(没有就凉凉)
- 先备份数据恢复
- 用mysqlbinlog命令将上述的binlog文件导出为sql文件,并剔除其中的drop语句
- 恢复binlog中增量数据的部分
5 补救措施
- 优先考虑是否能只通过binlog恢复,不能的化,再考虑其它
- 执行 DROP DATABASE / DROP TABLE 命令误删库表时,如果采用的是共享表空间模式,还有恢复的机会。如果不是,直接从备份文件恢复吧;在共享表空间模式下,误删后立刻杀掉(kill -9)mysql相关进程(mysqld_safe、mysqld),然后尝试从ibdataX文件中恢复数据;
- 误删除正在运行中的MySQL表ibd或ibdataX文件。利用linux系统的proc文件特点,把该ibd文件从内存中拷出来,再进行恢复,因为此时mysqld实例在内存中是保持打开该文件的,切记这时不要把mysqld实例关闭了。此模式恢复,需要停止线上业务对该实例的写入操作,不再写入新数据,防止丢失新数据。把复制出来的ibd 或 ibdataX文件拷贝回datadir后,重启mysqld进入recovery模式,innodb_force_recovery 选项从 0 - 6 逐级测试,直至能备份出整个实例或单表的所有数据后,再重建实例或单表,恢复数据。
- 未开启事务模式下,执行delete误删数据。发现问题严重性后,立即将mysqld(以及mysqld_safe)进程杀掉(kill -9),然后再用工具将表空间数据读取出来。因为执行delete删除后,实际数据并没有从磁盘清除,只是先打上deleted-mark标签,后续再统一清理,因此快速杀掉进程可以防止数据被物理删除。
- 执行truncate误清整张表。如果没使用共享表空间模式的话,直接使用备份恢复和binlog恢复。
- 执行不带where条件的update,或者update错数据。数据规模大没法补救的话,也只能通过走备份恢复和binlog恢复。
6 相关操作
查看是否开启binlog日志
# log_bin是ON,就说明打开了 OFF就是关闭状态。 show variables like 'log_bin'; # log_bin相关的内容都能查到 show variables like '%log_bin%'; # 设置开启log_bin 一般情况下都是通过配置进行设置 SET SQL_LOG_BIN=1
binlog日志位置
show variables like '%datadir%';
根据binlog日志恢复数据
- cd 到binlog文件目录
- mysql安装目录/mysql/bin/下找到binlog日志解析工具mysqlbinlog
通过mysqlbinlog工具命令按照对应时间解析binlog日志内容,输出到新的文件中
该工具也支持过滤指定表的相关操作记录
mysqlbinlog --no-defaults --database=test --start-datetime="2021-11-10 09:00:00" --stop-datetime="2021-11-10 20:00:00" /data/mysql/mysql-bin.000020 > binlog.txt
利用解析出来的sql进行恢复或者根据需要恢复的位置,使用命令进行恢复
mysqlbinlog --start-position=8000 --stop-position=8888 mysql-bin.000020 |mysql -uroot -p123456;
通过配置文件对binlog 日志进行配置
# 日志格式 # Statement模式,每一条会修改数据的sql都会记录在binlog中。 # Row模式,5.1.5版本的MySQL才开始支持row,它不记录sql语句上下文相关信息,仅保存哪条记录被修改。 # Mixed模式,一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。 # 设置日志格式 binlog_format = mixed # 设置日志路径,需要注意的是该路经需要mysql用户有写权限 log-bin = /data/mysql/logs/mysql-bin.log # 设置binlog清理时间 expire_logs_days = 7 # binlog每个日志文件大小 max_binlog_size = 100m # binlog缓存大小 binlog_cache_size = 4m # 最大binlog缓存大小 max_binlog_cache_size = 512m
各位大佬,删库请慎重!!!