记录一场Mysql删除重复数据引发的风波

像往常一样, 韩大大例行处理着产品比巴的需求和数据处理任务。天知道今天怎么就差点删库跑路了,这都是后话。下面进入正题,问题的起源来自一个去重的任务,某大表中有业务逻辑中判断为重复的数据 需要后台数据库直接删除。
我们用的数据库是mysql,大表数据大概1000万,每日凌晨备份,昨天上午10点左右要处理3900个重复数据,像oracle习惯那样写了去重sql 执行报错,因为mysql不支持查询某表的同时删除,所以想到了创建一张临时表来保存重复数据唯一主键id’,然后通过in id 来删除。这看似都没有问题,在数据库一炮打响,没有开启事务的按钮也就没用, 天知道这货居然清空了我的表,1000万核心数据瞬间干掉,当时大大心一沉,当然表面没有变现出来,马上想解决方案。
我脑子瞬间出现了两个解决方式:1.恢复凌晨的备份,但是今天新增的23000+数据就会丢失 2.用我博学的知识储备–baidu找找解决方案,记得有个binlog功能可以通过日志恢复数据,前提是我们的云上数据库开启了此功能。
颤颤巍巍的找了下,开启了还好,这里的linux操作交给了运维。于是我开始去找问题的原因,事故责任人sql如下: delete from score where id in (select id from score_copy); 其中score_copy的内容来自查重后的id,怎么看都没有问题,于是我又建了两个小表添加了几条数据去测试,没有问题,证明sql是对的,于是陷入了僵局,此处省略几个小时的挣扎,其中运维那里运用binlog也不是很顺利,因为binlog只有当前天内的执行脚本, 所以恢复数据还是要首先恢复前一天的备份,然后log中取出来的sql都是残疾,例如 update score set status = 然后后面具体的东西都没了,后来据说是取了2.4G的log 然后连同查询一起执行了, 整个恢复用时超过8小时。
好继续探讨这个sql为什么为干掉整张表,偶然实验中发现,score_copy中没有数据时,执行删除会删除所有数据,但是很奇怪,里面是有数据的,于是打开了设计表,发现了字段前面竟然有空格,你没看错,字段出了空格,于是查询出来是空而不是报错,真奇葩。附赠罪魁祸首建表sql:
创建中间表
create table score_copy(
  id int primary key
)Engine=InnoDB default charset utf8;
好了,如果大家不想痛苦,请谨慎尝试此建表sql。再赠送一个msyql恢复数据的博客:tps://www.cnblogs.com/-mrl/p/9959365.html ,使用mysql的朋友一定要记得开启binlog。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值