差点儿删库跑路

说到删除跑路,可能都是同情别人,没想到今天自己也成当事人了,想想都背后发凉。

事件起因

我们有一台机器,放置提供给第三方的接口,代码经常有落后,今天准备更新db和代码。

准备过程

代码库中有最新dump出来的含有DDL的sql文件。

source之前用vi打开并搜索了下,关键字是’drop’,然而搜索是区分大小写的,也没有仔细看(因为之前不包含drop语句),就疏忽了。

发现问题

因为之前导出的sql里面是没有drop语句的,所以source的时候,已存在的表会报错。

我在source的过程中发现都执行成功了, 所以。。。肯定是出问题了。

解决过程

1。 首先想是否有备份, 但是这台机器上我们没有做备份。

2。 没有备份, 那就只能从binlog恢复了(还好开启了binlog), 恢复过程中需要注意的点:

  • 因为只误删了一个库的数据, 所以不能影响其他的库

  • source导入的drop语句也会记录到binlog, 所以需要注意不能再把drop语句恢复(也就是又删一次), 即确认好恢复的位置。

在数据库的目录(/var/lib/mysql/)下有多个binlog文件, 最新的是mysql-bin.000023, 所以在mysql客户端中执行如下命令:

show binlog events in 'mysql-bin.000023'\G

输出是类似这样子的:

*************************** 8。 row ***************************
   Log_name: mysql-bin。000023
        Pos: 832
 Event_type: Query
  Server_id: 1507222038
End_log_pos: 1107
       Info: use `admincenter`; update `admins` set `login_time` = '2018-11-07 15:27:28',`login_expire` = '2018-11-08 03:00:00',`login_ip` = '223。71。45。209',`login_token` = '4133ef2a401c5c55fb321729897e912c',`id` = '114' where `id`='114'
*************************** 9。 row ***************************

我们找到DROP TABLE xxx语句, 也即我们删除表开始的语句, 并且定位到end_log_pos, 例如上面的: 1107。

通过搜索mysqlbinlog命令, 确认了几个参数, 即:

sudo mysqlbinlog --stop-position='1107' -d assets  mysql-bin.000023 > ~/000023.sql

这个命令导出的sql是: 1107这个位置之前所有的assets库的操作, 然后我们将sql文件source到数据库内即可。

如果在stop position后还有数据需要导入, 我们再执行一次命令, 加上开始和结束位置, 例如:

sudo mysqlbinlog --start-position='2200' --stop-position='3107' -d assets  mysql-bin.000024 > ~/000024.sql

对于老的binlog文件,我们可以使用下面的命令, 因为所有的数据都是我们需要恢复的:

sudo mysqlbinlog -d assets  mysql-bin.000022 > ~/000022.sql

最后把所有的binlog都导入一下就可以了。

写在最后

事发之后,还是很心跳,这种错误完全是自己不细心导致的,如果真的衍生出严重的问题,是需要负很大的责任的。

最后,真爱生命,认真工作。

(完)