MySQL旧数据清理

Posted on Aug 9, 2023

背景

在SAAS应用中,随着时间的推移用户的数据会越来多,磁盘空间的占用也会越来越大。如果用户停止使用,数据还保持在数据库,这可能会导致一些问题:

  1. 存储成本增加
  2. 数据库性能下降

针对这些问题就需要做一些数据清理工作,降低成本,提供数据库查询效率。这里分为两个部分清理:

  1. 用户数据清理
    1. 如果用户很长时间(几年)不在使用,那么可以考虑将用户关联的数据删除。
  2. 基于时间的清理
    1. 如保留最近两年,那么根据创建时间字段,将两年前的数据删除。
    2. 如果有做分区(时间),那么将两年前的分区删除。

MySQL数据清理的方式

使用DELETE语句

DELETE FROM table WHERE condition;

使用where条件来过滤要删除的数据,这种方法操作简单,不过如果要一次性删除大量的数据可能会导致性能问题,因为DELETE语句为锁定数据,可能需要很长的时间来执行。

也有办法来减少执行时间,降低删数据的性能影响:

  1. 分批删除
    • 通过limit子句,将大的删除分成多个批次进行,以减轻数据库的负载。
    • 如果要删除100万行的数据,可以分为100个批次,每个批次删除1000条数据。
DELETE FROM table WHERE condition limit 1000;

使用临时表备份

在删除大量数据之前,创建一个临时表,将要保留的数据复制到临时表,然后删除原始表的数据。这样可以保留备份,以防意外发生,不会影响数据库查询。

一些开源工具如gh-ost可以做在线迁移,不过它不能指定where条件来做数据过滤。DTS是阿里云的数据同步产品,可以跨云、跨实例迁移,也支支持同一个数据库的迁移,支持where条件。

使用TRUNCATE TABLE

如果需要删除整个表的数据,可以考虑使用TRUNCATE TABLE语句。这比DELETE语句更快,因为它会直接清除表中的数据而不是逐行删除。

使用删除分区的方式

删除分区

ALTER TABLE t1 DROP PARTITION p0, p1;

删除表空间

ALTER TABLE t1 DISCARD PARTITION p0, p1 TABLESPACE;

使用DTS清理旧数据

操作步骤:

  1. 新增同步任务
  2. 源库与目标库选择同一个
  3. 高级设置
    1. 修改目标表名字,添加后缀_dts
    2. 修改表同步设置,添加where条件
  4. 用新表替换旧表