记一次在phpmyadmin中将帝国cms数据表误清空的恢复过程
笔者采用帝国cms开发了一整套信息展示与计算系统,其中展示端只提供数据存储,而计算端采用独立的服务器,在计...
笔者采用帝国cms开发了一整套信息展示与计算系统,其中展示端只提供数据存储,而计算端采用独立的服务器,在计算完成后向主端post数据,由于数据量越来越大,小编进行了传输通道的优化,但疏忽了正确性校验问题,由于将小于号<误写为大于号>,导致数据存储表共计170万余条数据被清空。
万幸78模板网小编在之前已经开启了mysqlbinlog二进制缓存功能,该功能虽对服务器缓存略有影响,但出现清库、删库,数据损毁等致命问题时,可有效的恢复数据,下面对数据恢复过程进行记录。
一、保存日志。
首先,我们第一之间对mysqlbinlog日志进行了封存,此次共计两个文件,分别为mysql-bin.000023、mysql-bin.000024。由于之前的数据库备份只到2019-02-03 22:17:04,后续的数据没有备份,我们需要在数据中把这部分提取出来重新入库。将两个日志文件下载到本地。
二、导出日志。
由于mysqlbinlog功能存储的日志为二进制,我们没有办法直接查看,所以我们本地搭建运行环境,首先将日志导出为sql版本。我们这里使用帝国cms官方提供的本地运行环境包。而后cmd内运行如下命令。
mysqlbinlog --database=cha G:\\data\mysql-bin.000023 --start-datetime="2019-02-03 22:17:04" --short-form --database=diguocms >> G:\\sql\data1.sql
运行命令后,报出如下错误:
ERROR: Error in Log_event::read_log_event(): 'Found invalid event in binary log', data_len: 103, event_type: 15
Could not read entry at offset 4:Error in log format or read error
我们判断此处可能是服务器上和本地的mysqlbinlog工具版本不一致,不同版本的日志不能共用所致,所以我们通过如下命令查看了两处的mysqlbinlog版本,服务器上版本为v3.3,本地则为v3.1,为此我们重新下载了mysq5.5的windowsx64版本,将3.3版本的mysqlbinlog替换到本地。
重新运行上面的命令,在G盘sql目录下生成了data1.sql,文件超过了1GB,编辑使用较为困难。为此,我们队时间进行控制,增加截止时间,分批次将数据导出。命令如下
mysqlbinlog --database=cha G:\\data\mysql-bin.000023 --start-datetime="2019-02-03 22:17:04" --stop-datetime="2019-02-05 22:17:04" --short-form --database=diguocms >> G:\\sql\data1.sql
这样我们就导出了若干个sql文件,将这些sql文件导入数据库即可。
三、分离语句。
首先我们只丢失了一个表,而且这个数据表只有增加和修改记录,所以我们只需分理处sql文件中该表的增加、修改语句即可,编写一个php脚本遍历sql文件,并分离出语句为txt文件,脚本如下。
<?php
//导出sql语句
$file = "G:/sql/data1.sql";
$arr = file($file);
$str = '';
$insert = "insert into phome_ecms_diguocms(";
$update = "update phome_ecms_diguocms";
foreach ($arr as $v){
if (stripos($v, $insert) !==false) {
$str .= $v.";\r\n";
}
}
file_put_contents("G:/sql/sql1.txt", $str);
?>
接下来我们使用navicat或phpmyadmin导入该文件即可。
万幸78模板网小编在之前已经开启了mysqlbinlog二进制缓存功能,该功能虽对服务器缓存略有影响,但出现清库、删库,数据损毁等致命问题时,可有效的恢复数据,下面对数据恢复过程进行记录。
一、保存日志。
首先,我们第一之间对mysqlbinlog日志进行了封存,此次共计两个文件,分别为mysql-bin.000023、mysql-bin.000024。由于之前的数据库备份只到2019-02-03 22:17:04,后续的数据没有备份,我们需要在数据中把这部分提取出来重新入库。将两个日志文件下载到本地。
二、导出日志。
由于mysqlbinlog功能存储的日志为二进制,我们没有办法直接查看,所以我们本地搭建运行环境,首先将日志导出为sql版本。我们这里使用帝国cms官方提供的本地运行环境包。而后cmd内运行如下命令。
mysqlbinlog --database=cha G:\\data\mysql-bin.000023 --start-datetime="2019-02-03 22:17:04" --short-form --database=diguocms >> G:\\sql\data1.sql
运行命令后,报出如下错误:
ERROR: Error in Log_event::read_log_event(): 'Found invalid event in binary log', data_len: 103, event_type: 15
Could not read entry at offset 4:Error in log format or read error
我们判断此处可能是服务器上和本地的mysqlbinlog工具版本不一致,不同版本的日志不能共用所致,所以我们通过如下命令查看了两处的mysqlbinlog版本,服务器上版本为v3.3,本地则为v3.1,为此我们重新下载了mysq5.5的windowsx64版本,将3.3版本的mysqlbinlog替换到本地。
重新运行上面的命令,在G盘sql目录下生成了data1.sql,文件超过了1GB,编辑使用较为困难。为此,我们队时间进行控制,增加截止时间,分批次将数据导出。命令如下
mysqlbinlog --database=cha G:\\data\mysql-bin.000023 --start-datetime="2019-02-03 22:17:04" --stop-datetime="2019-02-05 22:17:04" --short-form --database=diguocms >> G:\\sql\data1.sql
这样我们就导出了若干个sql文件,将这些sql文件导入数据库即可。
三、分离语句。
首先我们只丢失了一个表,而且这个数据表只有增加和修改记录,所以我们只需分理处sql文件中该表的增加、修改语句即可,编写一个php脚本遍历sql文件,并分离出语句为txt文件,脚本如下。
<?php
//导出sql语句
$file = "G:/sql/data1.sql";
$arr = file($file);
$str = '';
$insert = "insert into phome_ecms_diguocms(";
$update = "update phome_ecms_diguocms";
foreach ($arr as $v){
if (stripos($v, $insert) !==false) {
$str .= $v.";\r\n";
}
}
file_put_contents("G:/sql/sql1.txt", $str);
?>
接下来我们使用navicat或phpmyadmin导入该文件即可。