当前位置: 首页 > news >正文

数据库丢失但没备份过?救星:二进制日志

前言

笔者之前的Haven项目,宝塔上的MySql经常自己关闭,重启MySql后数据库丢失。奈何我有备份,根本不怕,丢失我就重建。

由于这个项目搁置了很久,它的服务器已经被我释放了。然而现在需要申请软著,于是我将Haven项目与我现阶段参与的SoulSprout项目共用同一个服务器(其实前者也就用了个数据库)。(SoulSprout体量比Haven大但从未出现过MySql宕机的问题,最近一个月我也就没有备份)

次日,数据库打不开,发现MySql又自己关闭了!(这Haven项目的数据库是不是有病毒啊,我真服了,截至现在,我仍不能断定MySql宕机的具体原因)。问题是SoulSprout这个项目的数据库没备份。咋恢复呢?

解决方法:通过二进制日志的信息恢复


Moudle 1 : 宝塔MySql宕机及表丢失原因分析

根本原因分析

1. 为什么数据库会自己关闭?
  • 可能的原因包括:服务器资源不足(内存、磁盘空间)、MySQL配置问题、系统崩溃、MySQL bug、强制重启服务器等。
  • 从二进制日志中,看到了很多强制关闭线程的警告,例如:
    [Warning] [MY-010909] [Server] /www/server/mysql/bin/mysqld: Forcing close of thread 75044 user: 'news'.
    这通常是因为在关闭MySQL时,有连接没有正常关闭,MySQL强制关闭它们。
2. 为什么重启之后表会丢失?

· 从日志中发现了一条 DROP database \soulsprout`` 语句。这意味着在某个时间点,执行了删除数据库的操作。

# 在二进制日志中发现的危险操作
DROP database  `soulsprout`

可能的发生场景

  • 应用程序或脚本错误执行了删除数据库的操作
  • 部署流程中的自动化脚本误操作
  • 数据库维护过程中的误操作
  • 恶意操作或安全漏洞被利用

但是,从二进制日志中我看到了多次创建和删除数据库的操作,例如:
DROP database soulsprout
CREATE USER ...
DROP USER ...
等等

这似乎不是一次意外,而可能是某种自动化脚本或部署流程中的操作。

另外,我们注意到在二进制日志中,在删除数据库之后,又有创建表和数据插入的操作。所以,实际上在删除数据库之后,数据库又被重新创建并使用了,直到最后一次删除操作后没有重新创建,然后我们遇到了问题。

3. 重启后表消失的机制
  1. MySQL正常关闭时会将内存中的数据刷写到磁盘
  2. 但异常关闭可能导致:
    • 数据文件损坏
    • 事务未完全提交
    • 表空间信息丢失
    • 重启时MySQL尝试恢复,但遇到 DROP DATABASE 指令执行


Moudle 2 : 完整的故障恢复流程梳理

第一阶段:问题诊断

步骤1:确认问题范围
# 检查数据库状态
/etc/init.d/mysqld status
# 检查数据目录
ls -la /www/server/data/soulsprout

发现:数据库目录存在但为空

步骤2:检查MySQL错误日志
tail -100 /www/server/data/iZbp1bhyfrb73bpfb49a4rZ.err

发现:大量强制关闭线程的警告,但无表结构相关错误

步骤3:检查二进制日志状态
# 确认二进制日志文件存在
ls -la /www/server/data/mysql-bin.00000*

第二阶段:恢复策略制定

关键发现
  1. 二进制日志文件完整存在(mysql-bin.000004, mysql-bin.000005)
  2. 二进制日志包含完整的数据操作记录
  3. 需要确定是否包含表结构定义
验证二进制日志内容
./mysqlbinlog /www/server/data/mysql-bin.000004 | grep -i "CREATE TABLE" | head -10

重要发现:二进制日志中包含完整的表结构定义!到这算是放心了,本来以为只有DML数据的操作信息,没想到也有DDL数据定义的信息

现在既能找到表结构信息,又能找到表数据信息,下面就简单了

第三阶段:执行恢复

步骤1:定位恢复起点
./mysqlbinlog --base64-output=decode-rows -v /www/server/data/mysql-bin.000004 | \
grep -A 10 -B 5 "CREATE TABLE \`user\`" | head -20

找到关键位置# at 6966

这是从binlog中提取出自 CREATE TABLE 语句之后的所有操作,跳过之前导致数据丢失的 DROP 语句。

步骤2:执行精准恢复
# 从第一个CREATE TABLE语句开始恢复
./mysqlbinlog --start-position=6966 --database=soulsprout \
/www/server/data/mysql-bin.000004 /www/server/data/mysql-bin.000005 | \
mysql -u root -p soulsprout
步骤3:处理恢复中的问题
  • 我遇到的问题Can't create database 'soulsprout'; database exists
    • 原因:我手动创建了数据库,所以出现了此问题
    • 解决方案:跳过CREATE DATABASE语句
步骤4:最终成功方案
# 清理环境
mysql -u root -p -e "DROP DATABASE soulsprout;"
mysql -u root -p -e "CREATE DATABASE soulsprout;"# 执行恢复
./mysqlbinlog --start-position=6966 --database=soulsprout \
/www/server/data/mysql-bin.000004 /www/server/data/mysql-bin.000005 | \
mysql -u root -p soulsprout

第四阶段:验证恢复结果

  1. 来到navcat查看数据库发现表以及数据全部恢复
  2. 进入网站,数据正常,业务正常

梳理一下整个流程

  1. 发现问题:MySQL重启后,表全部消失。
  2. 检查数据目录:发现数据库目录(soulsprout)存在,但里面没有表文件(.frm, .ibd等)。
  3. 检查二进制日志:发现二进制日志(mysql-bin.000004和mysql-bin.000005)还在,并且其中包含了完整的数据库操作(包括创建数据库、创建表、插入、更新、删除等)。
  4. 尝试从二进制日志恢复:
    a. 首先,我们尝试直接使用二进制日志恢复,但遇到了错误,因为二进制日志中包含删除数据库的语句,而数据库已经存在。
    b. 然后,我们检查了二进制日志中是否包含表结构,发现确实有CREATE TABLE语句。
    c. 我们通过找到第一个CREATE TABLE语句的位置(position 6966),然后从这个位置开始恢复,跳过了之前的删除数据库操作。
    d. 在恢复过程中,我们遇到了表已存在的错误,因此我们选择了删除现有数据库,然后重新执行恢复。
    e. 最终,我们成功恢复了数据库的表结构和数据。

Moudle 3 : 预防措施建议

1. 备份!!!

  建议的备份方案:使用宝塔面板的自动备份功能,每日全量备份 + 每小时增量备份

2. 数据库配置优化

确保二进制日志开启,这也是我能在没有备份的情况下重新恢复数据库的根本原因

# 在my.cnf中增加安全配置
[mysqld]
# 确保二进制日志开启
log-bin=mysql-bin
# 设置二进制日志过期时间(建议7-30天)
expire_logs_days=7
# 启用慢查询日志
slow_query_log=1
# 设置安全参数
local_infile=0
3. 权限管理加强
-- 限制DROP权限
REVOKE DROP ON *.* FROM 'application_user'@'%';
-- 创建专用备份用户
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'strong_password';
GRANT SELECT, RELOAD, LOCK TABLES ON *.* TO 'backup_user'@'localhost';

http://www.dtcms.com/a/449375.html

相关文章:

  • 【C++实战(74)】深入C++安全编程:密码学实战之旅
  • inbound 概念及题目
  • UNet改进(43):SaFA-MS-UNet如何提升图像分割精度?
  • 网站建设中的智能元素凡科建站代理商登录
  • Elasticsearch 之分页查询
  • apache hop 不能处理clickhouse 数组格式怎么办?
  • 网站建设 网站设计php语言网站开发公司北京
  • 代码审计
  • 制作网站需要钱吗天津网址
  • cursor使用之没有正常的编辑器中的运行箭头
  • 建设网站优化创意网站建设价格多少
  • soular入门到实战(3) - 如何实现TikLab工具链统一登录认证
  • Python图形界面——海龟绘图
  • 《强化学习数学原理》学习笔记9——值迭代算法
  • 网站建设 统一标准体系什么是网络销售
  • 网站开发语言有哪几种临沂专业网站制作
  • 花店网站建设方案网站木马文件删除
  • Bash 的基本语法总结
  • 网站怎么进行优化网站开发 英文文章
  • 自动驾驶决策规划算法(开幕式)
  • 从零起步学习Redis || 第八章:过期删除策略与内存淘汰策略详解及实战使用(LRU和LFU算法详解)
  • 自动驾驶中的传感器技术65——Navigation(2)
  • 知识体系_scala_利用scala和spark构建数据应用
  • 备案后网站打不开沈阳营销网站建设
  • AI编辑器(FIM补全,AI扩写)简介
  • 优设网设计师导航最新seo快排技术qq
  • 【C++】哈希和哈希封装unordered_map、unordered_set
  • VS Code安装即环境配置
  • 从 LiveData 到 Flow:状态、事件、背压与回调全面实战
  • 数据库与缓存数据一致性的全部方案