手动删除 Matomo/Piwik 历史日志(MySQL删除大量数据)

不知不觉间,Piwik数据的容量已经达到500GB,虽然并没有感觉到性能有什么影响,但也是时候考虑如何清理其最占空间的访问记录数据了。于是决定拿备份库演练一番:

首先想到的是使用后台的自动清理功能,但是发现其每次10000条的删除能力,对于此等量级的数据可谓是杯水车薪。最后只能翻看源码,得出最基本的两条删除语句。

DELETE FROM `wk_log_conversion` WHERE server_time < '2021-01-01 00:00:00';
DELETE FROM `wk_log_visit` WHERE visit_last_action_time < '2021-01-01 00:00:00';
DELETE FROM `wk_log_link_visit_action` WHERE server_time < '2021-01-01 00:00:00';

至于 wk_log_action 这个表里是被引用的内容,下次遇到相同的引用内容,仍然需要添加一条记录。不删除反而可以确保idaction的唯一性。

至此,我们将遇到第二个问题:

如果要从InnoDB大表中删除许多行,则可能会超出表的锁定表大小InnoDB。也许删除500G的数据需要8个小时左右。

为了避免这个问题,或者只是为了最小化表保持锁定的时间,官方给出以下策略(根本不使用 DELETE):

  • 选择不要删除的行到与原始表具有相同结构的空表中

    INSERT INTO t_copy SELECT * FROM t WHERE ... ;
  • 使用RENAME TABLE以原子移动原始表的方式进行,并重新命名拷贝到原来的名称

    RENAME TABLE t TO t_old, t_copy TO t;
  • 删除原始表

    DROP TABLE t_old;

最终,我们优化查询如下

CREATE TABLE wk_log_conversion_copy LIKE wk_log_conversion;
INSERT INTO wk_log_conversion_copy SELECT * FROM wk_log_conversion WHERE server_time >= '2021-01-01 00:00:00';
RENAME TABLE wk_log_conversion TO wk_log_conversion_old, wk_log_conversion_copy TO wk_log_conversion;

CREATE TABLE wk_log_visit_copy LIKE wk_log_visit;
INSERT INTO wk_log_visit_copy SELECT * FROM wk_log_visit WHERE visit_last_action_time >= '2021-01-01 00:00:00';
RENAME TABLE wk_log_visit TO wk_log_visit_old, wk_log_visit_copy TO wk_log_visit;

CREATE TABLE wk_log_link_visit_action_copy LIKE wk_log_link_visit_action;
INSERT INTO wk_log_link_visit_action_copy SELECT * FROM wk_log_link_visit_action WHERE server_time >= '2021-01-01 00:00:00';
RENAME TABLE wk_log_link_visit_action TO wk_log_link_visit_action_old, wk_log_link_visit_action_copy TO wk_log_link_visit_action;

DROP TABLE wk_log_conversion_old, wk_log_visit_old, wk_log_link_visit_action_old;

官方文档链接 https://matomo.org/faq/how-to/faq_20184/

文章作者: 若海; 原文链接: https://www.rehiy.com/post/127/; 转载需声明来自技术写真 - 若海

添加新评论