如何安全地旋转postgresql表?

如何安全地旋转postgresql表?

我有一张 pgsql 表,它变得非常大。我想使用 cron 作业轮换它 - 数据仅用于生成报告,一两周后就不再需要它了。

答案1

正确的方法是设置表分区。

http://www.postgresql.org/docs/8.2/static/ddl-partitioning.html

您在列上建立检查约束,然后使用由该检查驱动的规则将插入父表的行定向到多个子表之一。对于您的情况,我建议按周进行分区。如果您想让用户查询单个分区,只需按逻辑命名分区 - 比如 2009_week_32 或 2009_august_week_1,然后让他们针对适当的表发出查询。

如果您希望他们一起查询多个表,则可以设置一个跨多个表进行联合选择的视图,然后用户查询该视图。

当您想要删除不再需要的数据时,只需修改表以更改规则并删除包含旧数据的表。

这比 disabledleopard 的答案要多一点工作量,但该技术在其他数据库引擎中相当常见。在时间戳列上使用“删除位置”的缺点是,在大型表上可能需要很长时间,并且数据会写入日志。Truncate 旨在解决日志写入问题,但您不能指定 where 子句。删除表非常快,因为您不需要处理单个行。

您需要进行某种维护来设置规则以涵盖未来日期。有些人每月编写此脚本(只需在月底前 5 天检查下个月的分区是否存在,如果不存在,则创建它并执行 alter table magic 来更改规则),而其他人则提前设置几个月或几年的规则,并根据需要每季度/每年手动执行维护工作。

答案2

我的想法是改变该表的模式来记录插入数据的时间戳。

ALTER TABLE blah ADD COLUMN entry_time timestamp DEFAULT current_timestamp;

这样,当前创建表的内容就不需要改变。

然后你的 cron 可能只是这个命令(应该适用于 postgres 8.x,但我没有运行服务器来确认,抱歉)

psql -c "DELETE FROM blah WHERE entry_time < (current_timestamp - interval '14 days') RETURNING *;" > deletelog.$( date "+%Y%m%d").log

编辑:我忘了提到“RETURNING *”位使 psql 返回所有已删除行的完整详细信息以及通常的“已删除的 N 行”,因此如果过早删除,可以使用此日志和一些 awk magic 来重新插入数据。此外,自动删除的审计日志始终是一个好主意。

相关内容