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

时间:2015-12-02 16:50:30

标签: mysql database partitioning

我有一个非常大的数据库。一列是时间戳,每天我想删除30天或更早的任何行。问题是随着时间的推移,数据库删除行并插入新行,新行可以插入先前被删除行占据的位置,从而创建关于时间戳的碎片数据库。当我去清理数据库时,碎片化的数据库将需要大量的时间来清理,因为MySQL必须通过整个数据库。

我想要使用的一个解决方案是为每天创建单独的分区甚至单独的数据库,这样每天都会自动创建一个新的分区来填充,每隔30天以上的分区自动删除。

我正在查看PARTITION命令,它似乎是追溯分区表。我想从头开始自动完成。

有没有人对如何做到这一点有任何见解?

编辑: 我使用snort和barnyard来清理数据库。我在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

如果数据库非常大,这似乎不切实际。它似乎也没有使用索引。

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

1 个答案:

答案 0 :(得分:0)

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

不要在InnoDB表上使用OPTIMIZE TABLE;它几乎总是不值得努力。

您在所有表格上都有一个复合INDEX(sid,cid)吗?

如果其他表上的DELETEs过于侵入(因为锁定很长),请参阅delete blog以了解有关侵入性较小的选项。