MySQL包含3亿数据的表只有3万条为有效数据时怎么清理异常数据

- 数据库

排查 MySQL 大表的时候,发现一个表由于业务显示有三亿的数据,但是这个表因为业务特性不应该有那么多数据的。和开发确认检查代码后发现是之前一个bug导致的(本来应该比对存在就更新数据的,bug导致比对失败每次都是插入数据了),bug修复后忘记要把异常数据删掉所以一直保留了下来。这里记录下操作过程。


方案说明

由于有效数据占总数据的比例太小了,所以 delete 异常数据再 OPTIMIZE TABLE 重建表的话成本就太高了。由于该表只有定时任务会才会有写操作,其他应用都是读,所以打算晚点业务低峰期直接把有效数据抽出来,和线上表替换下表名就行了。

创建临时表存储有效数据

基于线上业务表结构创建一个空的临时表,用于存储有效数据。

create table kernel_xxx_statis_zcy_temp like kernel_xxx_statis;


插入有效数据到临时表

代码bug期间新插入的异常数据 xxxId 的字段值为 null ,所以只要筛选非空的就是有效数据,insert into 插入到临时表即可。

insert into kernel_xxx_statis_zcy_temp select * from kernel_xxx_statis  where xxxId is not null;


更改线上业务表为其他名字

要先把业务表改成其他名字,等下才能把存储有效数据的临时表改名为业务表名。

RENAME TABLE kernel_xxx_statis TO err_kernel_xxx_statis;


更改临时表为业务表名

RENAME TABLE kernel_xxx_statis_zcy_temp TO kernel_xxx_statis;

等定时任务下一个执行时间,查看数据更新正常,完事。