如何从 MYSQL innodb 表中自动删除 6 个月前的数据

Jat*_*eth 7 mysql innodb partitioning

我有一个非常大的表,我每天都在其中获取数据,而且它的大小每天都在变大,但对于我的软件,只有 6 个月的数据有用。因此,我计划删除超过 6 个月的数据。我知道我可以使用 CRON 作业来完成,但我想使用 MYSQL 方式自动删除旧数据。我PARTITION也读过,我的问题是我可以使用它PARTITION还是我必须找到一些替代方法?

Ale*_*der 9

事件调度程序允许根据时间表执行常规事件。我在 Stack Overflow 上的帖子中有详细的示例,您只需将时间间隔值从 24 小时更改为 6 个月即可。

首先,确保事件调度程序已启用。要启用它,请使用

SET GLOBAL event_scheduler = ON;
Run Code Online (Sandbox Code Playgroud)

之后,您可以创建事件来检查行创建时间并删除旧记录。例如

CREATE EVENT cleaning ON SCHEDULE EVERY 1 MONTH ENABLE
  DO 
  DELETE FROM MyTable
  WHERE `timestamp_column` < CURRENT_TIMESTAMP - INTERVAL 6 MONTH;
Run Code Online (Sandbox Code Playgroud)

如果表中没有带有行创建时间戳的列,那么您可以创建触发器,将当前时间戳和插入的行标识符插入到辅助表中。

CREATE TRIGGER logCreator AFTER INSERT ON MainTable
  FOR EACH ROW 
  INSERT INTO LogTable (MainID, Created) 
  VALUES(NEW.id, CURRENT_TIMESTAMP);
Run Code Online (Sandbox Code Playgroud)

然后您可以使用此日志获取特定时间之前创建的主表行的键并删除相应的记录。

delimiter |
CREATE EVENT cleaning ON SCHEDULE EVERY 1 MONTH ENABLE
  DO
  BEGIN
    DECLARE MaxTime TIMESTAMP;
    SET MaxTime = CURRENT_TIMESTAMP - INTERVAL 6 MONTH;
    DELETE FROM MainTable
    WHERE id IN (SELECT MainID FROM LogTable WHERE Created < MaxTime);
    DELETE FROM LogTable
    WHERE LogTable.Created < MaxTime;
  END |
delimiter ;
Run Code Online (Sandbox Code Playgroud)


IGG*_*GGt 1

这正是我目前所做的。我按月对表进行分区,然后在下个月开始时,我对drop最旧的事件运行 MySQL 计划事件,并创建一个新事件。这样,一切都由 MySQL 内部处理。

当然能否分区首先取决于你的表结构。(加上最初设置分区可能需要一些时间,具体取决于表的大小)。

请参阅如何拆分 MySQL 表文件?