MySQL数据恢复“天花板“
Posted _雪辉_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL数据恢复“天花板“相关的知识,希望对你有一定的参考价值。
文章目录
一、背景
在我们使用数据库时,难免会碰到数据被误删的情况,可能是业务错误操作、代码bug;也有可能是运维操作失误等等;但是我们可以将所有操作分为以下几类:
- DML导致数据丢失
- DDL导致数据丢失
- 数据文件损坏
二、DML导致数据丢失
首先DML导致的数据丢失
2.1 binlog闪回
使用逆向解析BINLOG工具来恢复:如binlog2sql、MyFlash、my2sql等
具体可以参考我的其他文章:
binlog2sql、MyFlash:
https://xuehui.blog.csdn.net/article/details/85067775
my2sql:
https://xuehui.blog.csdn.net/article/details/114819239
三、DDL导致数据丢失/数据文件损坏
3.1 全备+binlog
mysql有逻辑备份mysqldump、mydumper等和物理备份xtrabackup两种全备方案;但是如果是全备场景建议使用物理备份xtrabackup
,使用mysqldump
备份核心表;加上binlog 来实现全量+增量指定时间点恢复
应急方案快速恢复某些表到:指定时间点https://xuehui.blog.csdn.net/article/details/108102998
3.2 延迟从库[不常用,性价比不高]
mysql支持延迟从库:添加选项CHANGE MASTER TO MASTER_DELAY = N
;该实例会永远延迟N秒;
当发生数据丢失时,使用以下方式恢复到指定位置:
UNTIL
#直到指定的GTID位置停下
SQL_BEFORE_GTIDS | SQL_AFTER_GTIDS = gtid_set
#直到指定的binlog位置停下
MASTER_LOG_FILE = ‘log_name', MASTER_LOG_POS = log_pos
#直到指定的relay log位置停下
RELAY_LOG_FILE = ‘log_name', RELAY_LOG_POS = log_pos
#直到slave上多个并行线程之前没有延迟差距了就停下
#因为多线程复制,不同线程的复制进度不一样,因此有差距
SQL_AFTER_MTS_GAPS
当我们既没有备份也没有延迟从库时,那么数据恢复就就要画一个问号了,因为剩下的手段根据实际情况,无法保证100%的数据恢复完整性和确定性
3.3 innodb_force_recovery
#逐级配置innodb_force_recovery
#mysqldump导出数据
#备份然后删除ibdata1、ib_logfile0、ib_logfile1、undo文件
#注释掉第一步的配置:innodb_force_recovery
#重启数据库
#登陆mysql,重建数据库,导入备份
innodb_force_recovery的6种设置:
1 (SRV_FORCE_IGNORE_CORRUPT): 忽略检查到的 corrupt 页。尽管检测到了损坏的 page 仍强制服务运行。一般设置为该值即可,然后 dump 出库表进行重建。这个选项对于备份或者转存当前数据尤为有用
2 (SRV_FORCE_NO_BACKGROUND): 阻止主线程的运行,如主线程需要执行 full purge 操作,会导致crash。 阻止 master thread 和任何 purge thread 运行。若 crash 发生在 purge 环节则使用该值。阻止恢复主线程的运行,如果清除操作会导致服务器挂掉
3 (SRV_FORCE_NO_TRX_UNDO): 不执行事务回滚操作。
4 (SRV_FORCE_NO_IBUF_MERGE): 不执行插入缓冲的合并操作。如果可能导致崩溃则不要做这些操作。不要进行统计操作。该值可能永久损坏数据文件。若使用了该值,则将来要删除和重建辅助索引。如果插入到缓冲区的合并操作会导致系统崩溃,将不会被执行
5 (SRV_FORCE_NO_UNDO_LOG_SCAN): 不查看重做日志,InnoDB 存储引擎会将未提交的事务视为已提交。此时 InnoDB 甚至把未完成的事务按照提交处理。该值可能永久性的损坏数据文件。
6 (SRV_FORCE_NO_LOG_REDO): 恢复时不做 redo log roll-forward。使数据库页处于废止状态,继而可能引起 B 树或者其他数据库结构更多的损坏。
3.4 fd恢复
当数据文件被物理删除时,如果此时数据库未被关闭,此时按照原理其实是没有被实际删除的,只是做了一个delete标记,可以通过/proc/$pid/fd中的文件,来进行尝试恢复,步骤如下:
#测试表
root@mysql 22:52: [sbtest]> select * from t1;
+------+
| id |
+------+
| 1 |
| 2 |
| 2 |
+------+
3 rows in set (0.00 sec)
#确认mysql pid
[root@iZbp1ir1m7i4bke4pg4fcxZ ~]# ps -ef | grep -w mysqld | grep -v grep
mysql 903 12825 0 2021 ? 00:03:03 /usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql --datadir=/data/mysql/mysql_data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/data/mysql/logs/error.log --open-files-limit=65535 --pid-file=mysql.pid --socket=/data/mysql/mysql_tmp/mysql.sock --port=3306
#模拟误删除
[root@iZbp1ir1m7i4bke4pg4fcxZ sbtest]# rm -f /data/mysql/mysql_data/sbtest/t1.ibd
#找到误删除的文件
[root@iZbp1ir1m7i4bke4pg4fcxZ ~]# ll /proc/903/fd/ | grep delete
lrwx------ 1 root root 64 Dec 31 00:49 13 -> /data/mysql/mysql_tmp/ibXUqQQZ (deleted)
lrwx------ 1 root root 64 Dec 31 00:49 40 -> /data/mysql/mysql_data/sbtest/t1.ibd (deleted)
lrwx------ 1 root root 64 Dec 31 00:49 6 -> /data/mysql/mysql_tmp/ibKYQhVM (deleted)
lrwx------ 1 root root 64 Dec 31 00:49 7 -> /data/mysql/mysql_tmp/ibskO54z (deleted)
#此时数据表依旧可以读取,加锁将文件拷回数据目录并赋权
root@mysql 22:52: [sbtest]> select * from t1;
+------+
| id |
+------+
| 1 |
| 2 |
| 2 |
+------+
3 rows in set (0.00 sec)
root@mysql 22:55: [sbtest]> lock tables t1 write;
Query OK, 0 rows affected (0.00 sec)
[root@iZbp1ir1m7i4bke4pg4fcxZ ~]# cp /proc/903/fd/40 /data/mysql/mysql_data/sbtest/t1.ibd
[root@iZbp1ir1m7i4bke4pg4fcxZ ~]# chown -R mysql.mysql /data/mysql/mysql_data/sbtest/t1.ibd
#重启数据库,恢复完成
3.5 三方工具恢复
3.5.1 extundelete(ext4)
对于ext4文件系统,可以使用extundelete工具在linux上进行数据恢复。
extundelete /dev/vda1 --inode 2 查看vda1分区根目录下面可被恢复的文件及文件夹
extundelete /dev/vda1 --restore-inode 12 恢复对应inode的文件
extundelete /dev/vda1 --restore-file filename 恢复单个文件
extundelete /dev/vda1 --restore-directory 恢复目录,空目录不会被恢复
extundelete /dev/vda1 --restore-all 恢复所有文件
3.5.2 undrop-for-innodb
undrop-for-innodb 是针对 innodb 的一套数据恢复工具,可以从文件级别恢复诸如:DROP/TRUNCATE table, 删除表中某些记录,innodb 文件被删除,文件系统损坏,磁盘 corruption 等情况
表结构恢复
#stream_parser 分析 ibd/ibdata 文件(或者挂载的磁盘)
./stream_parser -f /data/mysql/mysql_data/ibdata1
#c_parser 分析页面中用户的行数据
$./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000002.page -t dictionary/SYS_COLUMNS.sql
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000004.page -t dictionary/SYS_FIELDS.sql
#sys_parser 恢复 CREATE TABLE 语句
./sys_parser -h 127.0.0.1 -u root -P 56160 -d recover sakila/actor
数据恢复
#stream_parser 分析 ibd/ibdata 文件(或者挂载的磁盘)
./stream_parser -f /data/mysql/mysql_data/ibdata1
./stream_parser -f /dev/vda1 -s 1G -t 50G
四、总结
1、运维操作自动化、业务账号权限最小化原则
2、错误操作后避免数据二次污染
3、做好数据、binlog备份;
4、规范使用binlog:binlog_row_image=FULL
、binlog_format=ROW
;保留时间可以衔接全备
以上是关于MySQL数据恢复“天花板“的主要内容,如果未能解决你的问题,请参考以下文章
Alibaba之MySQL宝典流出!极致经典,堪称行业天花板
薪水界的天花板!一文助我拿下十多个offer:精选并发+JVM+多线程+Netty+MySQL,达到这个境界就可以躺平啦~