暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

TimescaleDB 大规模删除操作的最佳实践

原创 刺史武都 2025-05-28
258

欢迎阅读 TimescaleDB 最佳实践系列的第二部分!在第一部分中,我们探讨了如何高效地执行大规模回填操作,并分享了一些优化性能和避免常见陷阱的技巧。如果您还没有阅读第一部分,可以通过此链接查看。

在今天的博客中,我们将讨论时间序列数据管理的另一个重要方面:大规模删除操作

随着数据随着时间的推移而增长,旧记录往往会失去其相关性,但会继续占用宝贵的磁盘空间,从而可能增加存储成本,如果管理不善,可能会降低性能。

让我们介绍一些清理或减少 TimescaleDB 中老化数据的策略,帮助您维护精简、高效且经济高效的数据库。

大规模删除操作的先决条件

以下是在生产中执行大规模删除时需要遵循的几个重要步骤,以确保我们在出现问题时做好准备。

调整 Autovacuum 设置

在 PostgreSQL 中,VACUUM是一个维护过程,用于移除死元组(UPDATE或DELETE操作留下的过时行版本)。这些死元组会占用空间,但对任何活动事务都不再可见。Vacuum 操作可以回收这些空间,有助于减少表膨胀并维护数据库性能。

自动清理功能会定期在后台运行,自动执行此过程,确保无需人工干预即可清理死行。这在执行大量删除操作后尤为重要,因为此时会累积大量死行。如果不及时处理,可能会导致表膨胀、I/O 增加以及查询性能下降。

然而,它的有效性很大程度上取决于配置的合理性。如果没有适当的调整,自动清理可能会运行频率过低或速度过慢,从而导致死元组堆积并影响性能。

以下是一些重要的自动清理参数及其推荐值的列表,可用于有效地调整自动清理。

自动清理

  • 描述:启用或禁用自动清理守护进程。
  • 默认值:开启
  • 建议:开启

autovacuum_max_workers

  • 描述:指定自动清理工作进程的最大数量。
  • 默认值:3
  • 建议:CPU 核心/8,但至少 3
  • 例如:如果 PostgreSQL 分配了 56 个 CPU 核心,则该值应为 56/8 = 7

autovacuum_naptime

  • 描述:自动清理运行之间的时间间隔。
  • 默认值:1分钟
  • 建议:30秒

autovacuum_vacuum_scale_factor

  • 描述:表大小的分数,决定了触发真空所需的更新或删除的元组的额外数量。
  • 默认值:0.2
  • 建议:0.05

autovacuum_analyze_scale_factor

  • 描述:表大小的分数,决定触发分析所需的更新或插入元组的额外数量。
  • 默认值:0.1
  • 建议:0.05

autovacuum_vacuum_cost_delay

  • 描述:自动清理工作者执行清理操作之间的成本延迟(以毫秒为单位)。
  • 默认值:20ms
  • 建议:100ms

autovacuum_vacuum_cost_limit

  • 描述:自动清理工作者执行清理操作的成本限制。
  • 默认值:-1(使用vacuum_cost_limit)
  • 建议:2000

log_autovacuum_min_duration

  • 描述:如果自动清理操作所用时间超过指定的持续时间(以毫秒为单位),则记录该操作。
  • 默认值:-1(禁用)
  • 建议:1000ms

autovacuum_work_mem

  • 描述:自动清理工作者处理每个表时使用的内存。
  • 默认值:-1(使用 maintenance_work_mem)
  • 建议:系统内存的 20% / autovacuum_max_workers
  • 示例:如果 PostgreSQL 分配了 300GB 内存,并且 autovacuum_max_workers 为 10,则该值应为 300 / 10 = 6 GB 的 20%。

执行大规模删除操作的方法

在本节中,我们将介绍在生产环境中执行大规模删除操作的几种关键方法。但是,强烈建议在将所选方法应用到生产系统之前,先在暂存环境中进行测试。

方法 1:使用 TimescaleDB 的数据保留策略

要执行大规模删除操作,Timescale 建议使用数据保留策略。数据保留策略会自动删除旧数据,从而帮助您节省存储成本。

数据保留策略意味着,一旦数据的时间值超过一定时间间隔,它就会自动删除数据。当我们创建数据保留策略时,Timescale 会自动安排后台作业来删除旧的数据块。

这就是我们可以添加数据保留策略的方法

SELECT add_retention_policy('test_table', INTERVAL '10 months');

在上面的例子中,我们在名为test_table的超表上创建了一个数据保留策略,指定任何超过10 个月的数据都应自动删除。

方法 1.1:使用保留策略和连续聚合对数据进行下采样

较旧的历史数据通常会被保留下来,以支持未来的分析需求,即使这些数据何时或如何使用尚不明确。因此,这些数据通常不会被删除,从而导致存储消耗随着时间的推移而增加。

为了解决这个问题,Timescale 提供了一种解决方案,允许删除数据,同时仍以聚合形式保留以供历史分析。这可以通过结合保留策略和连续聚合来实现。

这意味着我们可以从超表中删除旧数据,而无需将其从任何连续聚合中删除。这种方法可以节省原始数据的存储空间,同时保留汇总数据以供历史分析。

使用此方法时,仔细配置与数据保留策略相关的连续聚合的 刷新间隔至关重要。

例如,如果您将数据保留策略设置为删除超过1 天的数据,并且连续聚合也配置为每1 天刷新一次,则存在刷新所需的原始数据在刷新发生时已被删除的风险。因此,连续聚合可能无法访问必要的数据,从而导致数据不完整或无用。

为避免这种情况,请始终确保数据保留期长于连续聚合的刷新窗口。这样,系统就有足够的时间在原始数据被删除之前更新聚合。

方法 2:在 TimescaleDB 中手动删除块

如果您希望更好地控制删除过程,并且更愿意手动管理而不是使用自动数据保留策略,则此方法可能更适合您。它允许您根据特定需求和要求选择和删除数据块。

从性能角度来看,使用 PostgreSQL DELETE命令逐行删除数据可能很慢。但按块删除数据会更快,因为它会从磁盘删除整个文件。它不需要垃圾收集和碎片整理。

您可以使用以下命令手动删除一个块:

SELECT drop_chunks('test_table', INTERVAL '24 hours');

这将从test_table hypertable中删除包含超过24 小时的数据块

方法 3:将选定的数据传输到新的 Hypertable

此方法在需要从超表中删除大量数据的情况下尤其有用,通常是当很大一部分数据不再需要时。与逐行删除或依赖保留策略相比,此方法可以实现更可控、更高效的清理。

以下是涉及的步骤

  • 定义一个具有相同模式的新超表,包括所有必要的列、索引和约束。
  • 仅将原始超表​​中相关或所需的数据子集插入/复制到新的超表中。这允许您在复制过程中丢弃不需要的数据。
  • 执行健全性检查或数据验证,以确保所有必要的数据都已准确地传输到新的超表。
  • 验证完成后,如果您对数据完整性有信心,请删除原始超表以回收存储。

当您能够明确定义哪些数据需要保留,并且现有数据中的大部分不再需要时,此方法最为有效。相比传统的删除方法效率低下或速度缓慢的情况,这种方法能够彻底清除数据,并有助于减少数据膨胀。

执行大规模删除操作后该怎么办
执行大规模删除操作后,建议在超表上运行VACUUM FULL,通过删除死元组并将释放的空间返回给操作系统来回收磁盘空间。

以下是您可以运行的方法

VACUUM FULL test_table

其中test_table是超表名称

结论

最后,我们建议遵循社区制定的指南,在超表上执行大规模删除操作。此外,请确保您的自动清理设置已正确调整,以便高效处理死元组并顺利回收存储。

原文地址:https://stormatics.tech/blogs/best-practices-for-timescaledb-massive-delete-operations
原文作者:Semab Tariq

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论