繁体   English   中英

MySQL-按日期对数据库或表进行分区以进行快速清理

[英]MySQL - Partitioning database or tables by dates for quick cleanup

我有一个非常大的数据库。 一列是时间戳记,我每天都想删除30天或更早的任何行。 问题在于,随着时间的流逝,数据库删除行并插入新行,新行可能会插入到先前被删除行占据的位置,从而创建相对于时间戳的碎片数据库。 当我去清理数据库时,碎片化的数据库将需要很多时间来清理,因为MySQL必须遍历整个数据库。

我想采用的一种解决方案是每天创建单独的分区甚至是单独的数据库,以便每天自动创建一个新分区以进行填充,而每隔30天以上的旧分区会自动删除。

我正在研究PARTITION命令,该命令似乎可以追溯性地对表进行分区。 我想从一开始就自动进行。

是否有人对此有任何见识?

编辑:我正在使用snort和bar来清理数据库。 我在cronjob中一直在做类似的事情:

use YOUR-SNORT-DB-NAME;
DELETE FROM event WHERE timestamp < DATE_SUB(NOW(),INTERVAL 28 DAY);
DELETE FROM data    USING data    LEFT OUTER JOIN event USING (sid,cid) WHERE event.sid IS NULL;
DELETE FROM iphdr   USING iphdr   LEFT OUTER JOIN event USING (sid,cid) WHERE event.sid IS NULL;
DELETE FROM icmphdr USING icmphdr LEFT OUTER JOIN event USING (sid,cid) WHERE event.sid IS NULL;
DELETE FROM tcphdr  USING tcphdr  LEFT OUTER JOIN event USING (sid,cid) WHERE event.sid IS NULL;
DELETE FROM udphdr  USING udphdr  LEFT OUTER JOIN event USING (sid,cid) WHERE event.sid IS NULL;
DELETE FROM opt     USING opt     LEFT OUTER JOIN event USING (sid,cid) WHERE event.sid IS NULL;
DELETE FROM acid_event USING acid_event LEFT OUTER JOIN event USING (sid,cid) WHERE event.sid IS NULL;
DELETE FROM ag USING acid_ag_alert AS ag LEFT OUTER JOIN event AS e ON ag.ag_sid=e.sid AND ag.ag_cid=e.cid WHERE e.sid IS NULL;
OPTIMIZE TABLE event, data, iphdr, icmphdr, tcphdr, udphdr, opt, acid_event, acid_ag_alert

如果数据库很大,这似乎是不切实际的。 它似乎也不使用索引。

我不是数据库专家,所以我想知道如何修改架构或清理脚本以提高性能。

是的, PARTITIONing对于从表中清除“旧”数据很有用。 那是PARTITIONing的极少数用途之一。 并使用PARTITION BY RANGE(TO_DAYS(...)) ,而不是BY HASH等。有关执行ALTERs详细信息和示例代码,请参见[ 我的博客 ]。 它建议大约有32个“每日”分区。

不要在InnoDB表上使用OPTIMIZE TABLE 这几乎总是不值得的。

您是否在所有表上都有一个复合INDEX(sid,cid)

如果其他表上的DELETEs侵入性太强(由于冗长的锁定),请参阅delete blog,以获取有关侵入性较小的选项的讨论。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM