更新时间,创建时间没写入到数据库怎么办?
2019-11-06 本文已影响0人
龚志丹
今天遇见一个很尴尬的问题,表字段包含created_at 和 updated_at分别为创建时间和修改时间,一段时间后,发现程序中途修改后,导致两个字段值都是为空。但是这两个值又比较重要,还是想办法修复下数据吧。
入手思路:mysqlbinlog
第一步:找到mysqlbinlog所存储的位置,dump到本地。
第二步:使用mysqlbinlog自带工具解析出base64 SQL文件。
mysqlbinlog --base64-output=decode-rows -d shard1 -v ./mysqlbin.000026 > 1.txt
命令解析:
--base64-output=decode-rows 为每行解析出base64输出
-d shard1 指定databases 为shard1
-v ./mysqlbin.000026 指定binlog日志文件
> 1.txt 输出结果至1.txt
第三步:对文本进行筛选,导出相关的库名和表名
grep -C2 -w 'INSERT INTO `shard1`.`gold_detail_log_20190701_4`' ./1.txt > gold_0.sql
第四步:使用php脚本对日志进行分析,获取每条sql的执行时间,就是创建时间
<?php
$filename = [
'./gold_0.sql'
];
$result = [];
foreach ($filename as $file) {
$handle = fopen ($file,"r");
while (!feof ($handle))
{
$buffer = fgets($handle);
$content = trim($buffer);
preg_match('/\#(.*?)server id/i',$content,$ma);
if ($ma) {
$tmp = explode(' ',trim($ma[1]));
$year = str_split($tmp[0],2);
$tmpTime = '20' . $year[0]. '-' . $year[1]. '-' . $year[2]. ' ' . ($tmp[1]?: $tmp[2]);
$result['time'][]= $tmpTime;
}
preg_match('/\@1=(\d{0,10})/i',$content,$ma1);
if ($ma1) {
$result['id'][]= $ma1[1];
}
}
if ($result) {
foreach ($result['id']as $k => $id) {
$result['ok'][$id]= $result['time'][$k];
}
}
fclose ($handle);
$tablename = '';
switch ($file) {
case './gold_detail_log_20190701_0.sql':
case './gold_0.sql':
$tablename = 'gold_detail_log_20190701_0';
break;
case './gold_detail_log_20190701_1.sql':
case './gold_1.sql':
$tablename = 'gold_detail_log_20190701_1';
break;
case './gold_detail_log_20190701_2.sql':
case './gold_2.sql':
$tablename = 'gold_detail_log_20190701_2';
break;
case './gold_detail_log_20190701_3.sql':
case './gold_3.sql':
$tablename = 'gold_detail_log_20190701_3';
break;
case './gold_detail_log_20190701_4.sql':
case './gold_4.sql':
$tablename = 'gold_detail_log_20190701_4';
break;
}
// 生成sql
foreach ($result['ok']as $id => $time) {
$sql = "update {$tablename} set created_at = '{$time}', updated_at = '{$time}' where id = {$id} and created_at is null;" . PHP_EOL;
file_put_contents('build.sql',$sql,FILE_APPEND);
}
$result = [];
}