公司的MySQL数据库在做日常巡检时发现丢失了一百万条数据,怎么办?

这是一起非常严重的数据丢失事件。请立即停止所有可能写入数据的操作,并按照以下紧急流程处理。注意:不要重启数据库,不要随意执行repaircheck命令,以免覆盖可能的恢复线索。

一、紧急止损与取证

1、禁止执行任何写入 / 删除 / 更新

禁止重启 MySQL

禁止执行 OPTIMIZE / TRUNCATE / DROP 等危险命令

设置数据库只读

SET GLOBAL read_only = ON;
-- 同时需要关闭super用户的写入权限
SET GLOBAL super_read_only = ON;

通知开发 / 业务暂停对丢失数据所在表的写入操作。

2、立即备份现场关键日志

将所有binlog文件完整拷贝到备份目录:

cp /var/log/mysql/binlog.* /safe/location/

执行以下命令保存现场:

-- 查看表当前数据量 SELECT COUNT(*) FROM 丢失数据表;

-- 查看表最后写入时间 SELECT MAX(create_time),MAX(update_time) FROM 丢失数据表;

-- 查看数据库状态 SHOW MASTER STATUS; SHOW SLAVE STATUS\G;

3、确认丢失范围

确定是哪张表、哪个时间范围的数据丢失

检查是否有其他表也受到影响

通过业务方确认丢失数据的大致特征

4、确认是真丢失还是查询条件错误

先排除低级问题:

是不是查询加了 WHERE 条件?

是不是连错库 / 连错表?

是不是被逻辑删除(is_deleted=1)?

-- 查是否被逻辑删除 SELECT COUNT(*) FROM 表 WHERE is_deleted=1;

二、排查原因

1、谁删的?

检查general_log(如果已开启);检查应用发布记录、数据库账号权限变更

2、怎么删的?

mysqlbinlog解析binlog,过滤DELETE语句:

mysqlbinlog --base64-output=decode-rows -vv binlog.0000xx | grep -C 20 "DELETE FROM your_table"

3、什么时间删的?

通过业务日志、监控系统定位最早发现缺失的时间点,结合binlog时间戳

4、常见原因

人为误操作:DELETE忘带WHERE、脚本逻辑错误

应用bug:代码中批量删除逻辑触发

触发器/存储过程:级联删除

主从问题:从库被意外写入后同步覆盖

黑客入侵/删库跑路

三、数据恢复

1、基于binlog回滚

定位删除事件在binlog中的位置
mysqlbinlog --start-datetime="2025-01-15 10:00:00" --stop-datetime="2025-01-15 11:00:00" binlog.0000xx > event.sql

查看当前 binlog 文件

SHOW MASTER STATUS;

记录:mysql-bin.000123

解析 binlog,找到误删除语句

mysqlbinlog --base64-output=decode-rows -v mysql-bin.000123 > binlog.sql

打开 binlog.sql 搜索:

DELETE FROM    DROP TABLE   TRUNCATE

找到删除时间点、位置号(pos)。

使用 binlog2sql 或 my2sql 等工具可以反向生成恢复SQL
pip install binlog2sql
binlog2sql --flashback --start-file=binlog.0000xx --start-position=123 --stop-position=456

将生成的恢复SQL在测试库验证
确认无误后,恢复回生产库(注意避开新的写入)

恢复命令示例:

python binlog2sql.py \

-h 127.0.0.1 -u root -p密码 \

-d 库名 -t 表名 \

--start-file="mysql-bin.000123" \

--start-position=4321 \

--stop-position=9876 \

--flashback > rollback.sql

执行回滚 SQL

mysql -u root -p 库名 < rollback.sql

2、主从架构

如果配置了延时复制从库(例如延时1小时),且数据丢失在此窗口内:

-- 在从库停止同步,并跳过错删的GTID
STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;  -- 谨慎使用
START SLAVE;
-- 然后从从库导出丢失数据

3、没有 binlog

找最近一次全量备份(xtrabackup/ mysqldump)

恢复到临时库

导出丢失表

导入生产库

四、恢复后验证与复盘

-- 1. 比对数据量
SELECT COUNT(*) FROM your_table WHERE create_time BETWEEN '时间范围';

-- 2. 抽样比对数据内容
SELECT * FROM your_table LIMIT 10 OFFSET 某个丢失段;

-- 3. 检查是否有主键冲突或数据乱序

加强规范

  • 限制 delete 权限
  • 必须加 where 条件
  • 重要操作前锁表或备份
  • 开启安全日志审计

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐