在 Postgresql 中处理分区表

A_C*_*A_C 5 postgresql partitioning

由于历史原因,我们过去常常在 Postgresql 数据库中使用一个非常大的表来存储基于时间的一系列测量值。经过长时间的使用,当表的大小达到 200+ GB 时,我们决定对其进行一些清理,比如只保留 90 天的数据,以加快速度并节省一些磁盘空间。

问题是,这样做delete from ... where clock_column < ...不会回收磁盘上的任何空间,因此我们需要VACUUM FULL在删除后保留它们。

由于我们无法承受如此长的时间停止数据库,因此我们决定采用分区方法并创建每日表,以便我们能够在时间到期时将它们一一删除。所以现在我们有了table(最初的、巨大的),并以 date 命名table160101table160102等等。

现在我想做:

  1. 初始表的备份(仅初始表)

    2.1 在其中进行一些清理(仅在其中)或

    2.2 也许简单地截断它(仅它)

但当我进行测试时,我看到COPY table TO 'file'创建了整个表的转储(两者和table全部等)。同样的方式,清除整个表,而不是第一个表(在测试服务器上测试)。table160101table160102TRUNCATE

当我在 中使用分区表时SELECT,我可以简单地说明ONLY选择要使用的表。但我找不到在COPYor中做到这一点的方法TRUNCATE

所以问题是:如何在不牺牲表中数据的情况下归档我的目标?

PS 我需要归档的是,当所有“每日”数据都在“每日”表中时,我只是不喜欢保留带有非常旧数据的初始大表。事实上,TRUNCATE唯一的想法就是好主意。

dez*_*zso 5

让我们快速查看COPY文档

COPY { table_name [ ( column_name [, ...] ) ] | ( query ) }
    TO { 'filename' ...}
    ...
Run Code Online (Sandbox Code Playgroud)

你的朋友将成为其中的query一部分。这意味着您不仅可以从表中复制,还可以从任意查询中复制。例子可以是:

COPY (SELECT * FROM ONLY your_table) TO '/path/to/dump.sql';
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 你必须指定一个绝对路径COPY
  • 使用\copyfrom通常更方便psql,因为它将转储复制到客户端计算机,而不是服务器。就您而言,这可能无关紧要。
  • 在实践中,保留每日表格通常过于细粒度。如果您的所有查询都可以使用约束排除,那么这可能一切都很好,否则您可能会注意到一些规划开销。