快速恢复数据的 6 种方案

MySQL关系型数据库数据库管理服务

大家好,我是苏三,又跟大家见面了。

前言

最近星球中有位小伙伴说:他不小心把测试环境MySQL表中所有数据都误删了,问我要如何快速恢复?

幸好他误删的是测试环境,非生产环境。

我遇到过,之前有同事把生产环境会员表中的数据误删除的情况。

这篇文章跟大家一起聊聊MySQL如果误删数据了,要如何快速恢复。

希望对你会有所帮助。

最近建了一些工作内推群,各大城市都有,欢迎各位HR和找工作的小伙伴进群交流,群里目前已经收集了不少的工作内推岗位。

扫码加苏三的微信:li_su223,备注:所在城市,即可进群。

picture.image

1.为什么数据恢复如此重要?

2023年某电商平台误删20万用户数据,导致直接损失800万

某金融机构DBA误执行DROP TABLE,系统停摆6小时

这些事故背后,暴露的是误删数据之后恢复方案的缺失。

数据丢失的三大元凶

  1. 人为误操作 (占75%): DELETE 忘加WHERE、 DROP TABLE 手滑
  2. 程序BUG (占20%):循环逻辑错误、事务未回滚
  3. 硬件故障 (占5%):磁盘损坏、机房断电

下面是数据丢失的主要原因:picture.image

那么,如果MySQL如果误删数据了,快速恢复数据的方案有哪些呢?

2.常见的数据恢复方案

方案1:Binlog日志恢复

该方案最常用。

适用场景 :误执行DELETE、UPDATE

恢复流程

picture.image

操作步骤

  1. 定位误操作位置
  
mysqlbinlog --start-datetime="2023-08-01 14:00:00" \  
           --stop-datetime="2023-08-01 14:05:00" \  
           mysql-bin.000001 > /tmp/err.sql  

  1. 提取回滚SQL(使用python工具)
  
# parse\_binlog.py  
import pymysql  
from pymysqlreplication import BinLogStreamReader  
  
stream = BinLogStreamReader(  
   connection\_settings = {  
       "host": "127.0.0.1",  
       "port": 3306,  
       "user": "root",  
       "passwd": "root"},  
   server\_id=100,  
   blocking=True,  
   resume\_stream=True,  
   only\_events=[DeleteRowsEvent, UpdateRowsEvent])  
  
for binlogevent in stream:  
   for row in binlogevent.rows:  
       if isinstance(binlogevent, DeleteRowsEvent):  
           # 生成INSERT语句  
           print(f"INSERT INTO {binlogevent.table} VALUES {row['values']}")  
       elif isinstance(binlogevent, UpdateRowsEvent):  
           # 生成反向UPDATE  
           print(f"UPDATE {binlogevent.table} SET {row['before\_values']} WHERE {row['after\_values']}")  

  1. 执行恢复
  
python parse\_binlog.py | mysql -u root -p db\_name  

方案2:延迟复制从库

该方案是金融级的方案。

适用场景 :大规模误删数据

架构原理

picture.image

配置步骤

  1. 设置延迟复制
  
STOP SLAVE;  
CHANGE MASTER TO MASTER\_DELAY = 1800; -- 延迟30分钟(1800秒)  
START SLAVE;  

  1. 误删后立即停止同步
  
STOP SLAVE;  

  1. 将延迟从库提升为主库
  
RESET SLAVE ALL;  
SHOW MASTER STATUS; -- 记录binlog位置  

方案3:全量备份+增量恢复

适用场景 :整表或整库误删

恢复流程

picture.image

操作步骤

  1. 恢复全量备份
  
mysql -u root -p db\_name < full\_backup\_20230801.sql  

  1. 应用增量日志(跳过误操作点)
  
mysqlbinlog --start-position=100 --stop-position=500 \  
          mysql-bin.000001 | mysql -u root -p  

方案4:Undo日志恢复

该方案是InnoDB特有的。

适用场景 :刚提交的误操作(事务未关闭)

核心原理

picture.image

操作步骤

  1. 查询事务信息
  
SELECT * FROM information\_schema.INNODB\_TRX;  

  1. 定位Undo页
  
SHOW ENGINE INNODB STATUS;  

  1. 使用undrop-for-innodb工具
  
./undrop-for-innodb/system\_parser -t user\_data /var/lib/mysql/ibdata1  

方案5:文件恢复

从物理备份中恢复,需要提前做备份。

适用场景 :DROP TABLE误操作

恢复流程

picture.image

操作步骤

  1. 安装恢复工具
  
yum install testdisk -y  

  1. 扫描磁盘
  
photorec /dev/sdb1  

  1. 重建表结构
  
CREATE TABLE user\_data (...) ENGINE=InnoDB;  

  1. 导入表空间
  
ALTER TABLE user\_data DISCARD TABLESPACE;  
cp recovered.ibd /var/lib/mysql/db\_name/user\_data.ibd  
ALTER TABLE user\_data IMPORT TABLESPACE;  

方案6:云数据库快照恢复

适用场景 :阿里云RDS、AWS RDS等云服务

操作流程(以阿里云为例)

picture.image

最佳实践

  1. 设置策略:
  • 保留7天快照
  • 每4小时增量备份
  • 误删后操作:
  
# 通过SDK创建临时实例  
aliyun rds CloneInstance --DBInstanceId rm-xxxx \  
                       --BackupId 111111111 \  
                       --PayType Postpaid  

3、恢复方案对比选型

| 方案 | 恢复粒度 | 时间窗口 | 复杂度 | 适用场景 | | --- | --- | --- | --- | --- | | Binlog日志恢复 | 行级 | 分钟级 | 中 | 小范围误删 | | 延迟复制从库 | 库级 | 小时级 | 高 | 核心业务数据 | | 全量+增量恢复 | 库级 | 小时级 | 高 | 整库丢失 | | Undo日志恢复 | 行级 | 秒级 | 极高 | 事务未提交 | | 文件恢复 | 表级 | 不确定 | 极高 | DROP TABLE操作 | | 云数据库快照 | 实例级 | 分钟级 | 低 | 云环境 |

4.如何预防误删数据的情况?

4.1 权限控制(事前预防)

核心原则:最小权限分配

  
-- 禁止开发直接操作生产库  
REVOKEALLPRIVILEGESON *.* FROM'dev\_user'@'%';  
  
-- 只读账号配置  
GRANTSELECTON app\_db.* TO'read\_user'@'%';  
  
-- DML权限分离  
CREATEROLE dml\_role;  
GRANTINSERT, UPDATE, DELETEON app\_db.* TO dml\_role;  

4.2 操作规范(事中拦截)

  1. SQL审核 :所有DDL必须走工单
  2. 高危操作确认 :执行DROP前二次确认
  
-- 危险操作示例  
DROP TABLE IF EXISTS user\_data; -- 必须添加IF EXISTS  

  1. WHERE条件检查 :DELETE前先SELECT验证

4.3 备份策略(事后保障)

黄金备份法则:321原则

  • 3份备份(本地+异地+离线)
  • 2种介质(SSD+磁带)
  • 1份离线存储

总结

下面给大家总了数据恢复的三要三不要。

三要

  1. 立即冻结 现场:发现误删马上锁定数据库。
  2. 优先使用Binlog :90%场景可通过日志恢复。
  3. 定期演练恢复 :每季度做恢复测试。

三不要

  1. 不要 心存侥幸 :认为误删不会发生在自己身上。
  2. 不要 盲目操作 :恢复前先备份当前状态。
  3. 不要 忽视监控 :设置删除操作实时告警。

设计系统时,永远假设明天就会发生数据误删。

当灾难真正降临时,你会发现所有的预防措施都是值得的。

最后欢迎加入苏三的星球,你将获得:100万QPS短链系统、复杂的商城微服务系统、苏三AI项目、刷题吧小程序、秒杀系统、商城系统、秒杀系统、代码生成工具等8个项目的源代码、开发教程和技术答疑。

系统设计、性能优化、技术选型、底层原理、Spring源码解读、工作经验分享、痛点问题、面试八股文等多个优质专栏。

还有1V1免费修改简历、技术答疑、职业规划、送书活动、技术交流。

扫描下方二维码,可以优惠30元:

picture.image

只有20张优惠券,数量有限,先到先得。

目前星球已经更新了5800+篇优质内容,还在持续爆肝中.....

星球已经被官方推荐了3次,收到了小伙伴们的一致好评。戳我加入学习,已有1900+小伙伴加入学习。

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
字节跳动 NoSQL 的实践与探索
随着 NoSQL 的蓬勃发展越来越多的数据存储在了 NoSQL 系统中,并且 NoSQL 和 RDBMS 的界限越来越模糊,各种不同的专用 NoSQL 系统不停涌现,各具特色,形态不一。本次主要分享字节跳动内部和火山引擎 NoSQL 的实践,希望能够给大家一定的启发。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论