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=FULLbinlog_format=ROW;保留时间可以衔接全备

以上是关于MySQL数据恢复“天花板“的主要内容,如果未能解决你的问题,请参考以下文章

Alibaba之MySQL宝典流出!极致经典,堪称行业天花板

MySQL笔记:B站康师傅天花板教程(持续更新)

薪水界的天花板!一文助我拿下十多个offer:精选并发+JVM+多线程+Netty+MySQL,达到这个境界就可以躺平啦~

湖仓一体天花板,大数据一站式SQL分析技术实践

数据分析人的职场天花板

Java面试笔记的天花板,禁止无效学习浪费脑细胞