我在InnoDB上有几个DDBB(MySQL 5.5.7。-FreeBSD)。 5年来我没有任何问题。我意识到定期检查表,优化,......
神秘的是,其中一个数据库的表从70(DELETE!)丢失了20行。几年前插入了这些行。他们之间没有关系(随机ID' s)。这是一张非常小的桌子。
经过几个小时的研究(和谷歌),我没有找到原因。我通过上次备份恢复了信息。
我查了一下:
WEB APP :
1)应用程序没有DELETE语句,只有SELECT或UPDATE。
2)没有DELETE ON CASCADE,没有外键。
2)受保护的SQL INJECT。
3)没有应用程序管理表(如phpMysqlAdmin)。
4)我的应用日志没有显示在这几个小时内尝试攻击或访问。
MYSQL :
1)所有行的验证都是在mysql控制台中直接进行的,不使用APP。
2)mysqlcheck:受影响的表中没有错误。
3)Mysqldump:没有转储消失的行,只剩下剩余的行。
4)错误日志:没有注册错误。
5)table.idb文件不包含丢失的记录,只包含剩余的行。
6)mysql用户只能在本地访问(通过IP)。
服务器:
1)任何人都访问过服务器。
2)HDD或控制器上没有发生错误。
3)我没有在系统日志中看到事件。
显然一切都是正确的。我不知道发生了什么。
我想到两个选择:
1)MySQL 5.5.7中的一个错误
2)在记录丢失的几个小时内,我正在进行一百万个INSERT和DELETE的导入(在不同的数据库上)。我不认为这个激烈的过程已经损坏了(没有跟踪)另一个数据库中的另一个表。
我担心它是否会再次发生!
谢谢!
更新1 @pala_建议我查阅bin-log(我没看过!)。
在bin-log 20中查询着名的DELETE!
我粘贴bin-log:
(...)
BEGIN
/*!*/;
# at 83069675
# at 83069772
# at 83070746
# at 83071672
# at 83072677
#150505 12:29:18 server id 168291 end_log_pos 83069772 Table_map: `affected_database`.`affected_table` mapped to number 583255
#150505 12:29:18 server id 168291 end_log_pos 83070746 Delete_rows: table id 583255
#150505 12:29:18 server id 168291 end_log_pos 83071672 Delete_rows: table id 583255
#150505 12:29:18 server id 168291 end_log_pos 83072677 Delete_rows: table id 583255
#150505 12:29:18 server id 168291 end_log_pos 83073123 Delete_rows: table id 583255 flags: STMT_END_F
### DELETE FROM affected_database.affected_table
### WHERE
### @1=xxxxxxx
### @2=xxxxxxxx
### @3=xxxxxxxxxx
### @4=xxxxxxxxx
### @5=xxxxxxxxx
### @6=xxxxxxxxx
### @7=xxxxxxxxxx
### @8=xxxxxxxxx
### @9=xxxxxxxxxx
### @10=xxxxxxxxxxxx
### @11=xxxxxxxxxxx
### @12=xxxxxxxxxxx
### @13=xxxxxxxxxxx
### @14=xxxxxxxxxxx
### @15=xxxxxxxxxxx
### @16=xxxxxxxxxxx
### @17=xxxxxxxxxxx
### @18=xxxxxxxxxxx
### @19=xxxxxxxxxxx
### @20=xxxxxxxxxxx
### @21=xxxxxxxxxxx
### @22=xxxxxxxxxxx
### @23=xxxxxxxxxxx
### @24=xxxxxxxxxxx
### DELETE FROM affected_database.affected_table
### WHERE
(...) x20
它是如何运行的?
由于
答案 0 :(得分:1)
DELETE
似乎实际上是根据您bin-log
运行的。更巧合的选项(MySQL中的错误,无关导入期间的问题(如果确实无关))似乎不太可能。
我们有两个选择: 1.“授权”但未知,例如您的代码库中有一个删除方法,但您只是找不到它或者有效登录的人运行了一个命令(您本身不需要应用程序,但您确实需要访问允许登录的服务器到你的数据库) 2.未经授权:有人获得了对您系统的访问权(并进行了清理),或者有人发现了sql-injection
很难说哪个是最有可能的。从你做过的检查中很难说你有多彻底,但是对于系统的访问(没有事件)和代码问题(防止注入)都很难完全找到。 另一方面,如果有很多人可以访问系统,那么很难将其排除在外。
如果你真的觉得这可能会再次发生,你应该启用general query log。这会给你一个暗示源。你可以每天查看它并旋转它以免它变得太大。
如果您的服务器存在偏执级问题,您可以尝试在外部保存日志,只有您有权访问:这样可以消除任何篡改证据。我自己也不会那么远。