标签: autovacuum

取消 PostgreSQL 中的 (AUTO)VACUUM 进程是否会使所有工作都变得无用?

在某些场合,并作出巨大的后updateinsertdelete从一个表,我已经开始了VACUUM FULL ANALYZE,以确保DB没有得到太臃肿。在生产数据库中做这件事让我发现这不是一个好主意,因为我可能会阻塞表很长一段时间。所以,我取消了这个过程,也许只是尝试了VACUUM(不是完整的)或者让AUTOVACUUM以后做任何它可以做的事情。

问题是:如果我在“中途”停止 VACUUM 或 AUTOVACUUM,是否所有已经完成的处理都丢失了?

例如,如果VACUUM已经找到 1 M 个死行并且我停止它,那么所有这些信息都丢失了吗?VACUUM 是否以完全事务的方式工作(“全有或全无”,就像大量的 PostgreSQL 进程一样)?

如果可以安全地中断 VACUUM 而不会丢失所有工作,那么有什么方法可以vacuum增量工作吗?[工作 100 毫秒,停止,等待 10 毫秒以允许非阻塞世界其他地方......等等]。我知道您可以通过调整 autovacuum 参数来完成部分工作,但我正在考虑能够以编程方式控制这一点,以便能够在某些时间/在某些条件下执行此操作。


注意:在这种情况下,停止/取消/终止进程意味着:

  • 如果使用 pgAdmin,请按“取消查询”按钮。
  • 如果以编程方式工作,请调用 pg_cancel_backend()。

我假设两者是等价的。我没有使用任何 shell/系统级 kill 命令。

postgresql maintenance vacuum autovacuum

14
推荐指数
1
解决办法
2万
查看次数

在有时很慢的大表上调试查询

我有一个由 Postgres 数据库支持的 Web API,性能通常非常好。我监控整个数据库和应用程序的性能。我的大部分查询(以及与此相关的 API 调用)都在不到 100 毫秒内完成,但偶尔会出现异常值。

就在今天,我收到一条警报,指出 API 调用耗时超过 5,000 毫秒,因此被看门狗终止。从挖掘日志开始,底层的 Postgres 查询花费了 13秒的时间来完成(一切都是异步的,所以即使 API 请求被终止,SQL 查询仍在继续)。

这是非常不典型的,即使当我手动运行有问题的查询时,我也无法重现这种糟糕的时间安排。它对我来说在 985 毫秒内完成(根据解释分析)。

我的问题

我不知道接下来还要看什么来尝试制定关于为什么会发生这种情况的理论。这种情况并不经常发生每天只有成千上万次类似事件发生一次或两次,但它确实经常发生,令人讨厌。我错过了什么?我应该下一步做什么来调试它?我不是来自 DBA 背景,所以这可能是一个愚蠢的问题。

一些快速背景和我尝试过的

这一切都托管在 Amazon 的 RDS 上,在 m3.xlarge 上运行 Postgres 9.4,预配置 IOPS (2,000)。

我的一个表,我们称之为“详细信息”相当大,包含近 500 万行,并且以每天 25,000 条记录的速度增长。这个表永远不会更新或删除,只是插入和选择,但代表了我的应用程序的“核心”——几乎所有感兴趣的东西都是从这个表中读取的。

在这个特定情况下,我知道这个查询有一些参数(例如底部的日期和 id),因此它正在查看一个相当大的数据集。我已经开发了这个查询的一个大大改进的版本,它将这个特定场景从 985 毫秒减少到 20 毫秒。但是,我担心这里还有其他“在起作用”的东西,一个查询需要不到一秒的时间来运行我,在生产中时不时需要超过 13 秒。

桌子

嗯,有点……它包含更多的列,但我删除了任何不在查询中或没有索引的列。以下查询中使用的所有列或附加索引的所有列都已保留;

CREATE TABLE "public"."details" (
    "value" numeric,
    "created_at" timestamp(6) WITH TIME ZONE NOT NULL,
    "updated_at" timestamp(6) WITH TIME ZONE NOT NULL,
    "effective_date" timestamp(6) …
Run Code Online (Sandbox Code Playgroud)

postgresql performance autovacuum amazon-rds postgresql-performance

9
推荐指数
1
解决办法
2922
查看次数

我应该在进行批量更新时禁用表上的自动清理吗?

我需要对表中的所有行执行简单的更新。该表有 40-50 百万行。在此期间删除索引和约束会UPDATE导致巨大的性能改进。

但是自动吸尘器呢?autovacuum 可以启动 aVACUUM还是ANALYZE在 a 的中间UPDATE?如果是这样,那会消耗机器资源的无用工作。我可以先在桌子上禁用它UPDATE,然后再重新启用它:

ALTER TABLE my_table
SET (autovacuum_enabled = false, toast.autovacuum_enabled = false);
-- Drop constraints, drop indexes, and disable unnecessary triggers

UPDATE my_table SET ....;

-- Restore constraints, indexes, and triggers
ALTER TABLE my_table
SET (autovacuum_enabled = true, toast.autovacuum_enabled = true);
Run Code Online (Sandbox Code Playgroud)

如果我在第一个之后不提交,这甚至有效ALTER吗?

另外,如果我在禁用它UPDATE,将它触发的更新,还是会因为它是他们中禁用它忽略这些更新?(我怀疑它会运行,但我宁愿确定。)

我现在正在使用 PG 9.3,但应该很快就会升级。因此,任何提及新版本更改的内容都值得赞赏。

postgresql bulk autovacuum

9
推荐指数
1
解决办法
6031
查看次数

Postgres 长时间自动清理停止数据库

我有一个相当大的表(100 万行),我的数据库卡在这个表上的自动清理(> 30 分钟)上,导致整个数据库阻塞。应用程序现在甚至不会加载。

-00:37:31.137859 autovacuum: VACUUM public.users
Run Code Online (Sandbox Code Playgroud)
SELECT n_tup_del, n_tup_upd FROM pg_stat_all_tables WHERE relname = 'users';
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

这些是我的用户表上的 autovacuum 设置:

-00:37:31.137859 autovacuum: VACUUM public.users
Run Code Online (Sandbox Code Playgroud)

我从慢 PostgreSQL 性能中使用的这些建议设置?不要忘记清空你的数据库

我只需要等待吗?我有哪些选择?

更新

我已升级到 Postgres 9.5,并将我的 RDS IOPS 增加到 900,并且真空过程仍然使 IOPS 达到最大值并且无法对数据库执行任何其他操作。该过程在升级前 1 天的某个时间点运行。

我还删除了我拥有的自定义 autovacuum 设置,现在只使用默认设置。

以下是这些查询结果的附件;

SELECT * FROM pg_stat_activity;
SELECT * FROM pg_stat_database;
SELECT * FROM pg_stat_user_tables;
SELECT * FROM pg_stat_user_indexes;
SELECT * FROM pg_locks;
Run Code Online (Sandbox Code Playgroud)

http://www.filedropper.com/output_5

postgresql aws postgresql-9.5 autovacuum

8
推荐指数
1
解决办法
3890
查看次数

小表会导致性能极度下降,已通过强制 VACUUM 修复。为什么?

我使用 PostgreSQL 9.6。

我有一个连接 17 个表的查询,其中 9 个有几百万行。查询运行良好,但本周其性能迅速下降。EXPLAIN 的输出没有帮助(所有扫描都是索引扫描,除了非常小的表),我不得不尝试从查询中删除表以隔离导致降级的表。

事实证明,一个包含 40 行的不起眼的表破坏了查询:800 ms 没有该表,而有 30 s。我在桌子上运行了 VACUUM FULL,它运行了大约一秒钟,现在性能恢复正常。

我的问题:

  1. 什么可以解释 <10kb 的表像这样破坏性能?
  2. 以后如何避免同样的问题?

在调试过程中,我对另一台服务器进行了基本备份,因此我有两个文件系统级别的数据库副本,其中一个我没有运行 VACUUM FULL。当我使用 pgAdmin 登录到 unvacuumed 副本时,我收到以下消息:

表“public.clients”上的估计行数与实际行数显着不同。您应该在此表上运行 VACUUM ANALYZE。

unvacuumed 表有 40 行计数和 0 估计。以下是屏幕截图中的其余统计数据。

pgAdmin 统计信息

postgresql performance statistics autovacuum postgresql-9.6 query-performance

6
推荐指数
1
解决办法
857
查看次数

UPDATE 是否会为未更改的 TOAST 值写入新的行版本?

我正在使用一个带有大型 TEXT 字段的 PostgreSQL 表,理论上该表会定期更新。我曾考虑过将数据直接存储在文件系统中,但使用 TOAST 时,数据已经存储在页外并压缩在数据库中,所以我想我会让事情变得简单,只使用数据库存储。

为了提供一些背景信息,我正在为 RSS 提要建立索引。我将每 24 小时运行一个脚本来提取 RSS 源并可能更新表格。这可能会导致大量死元组,从而占用大量磁盘空间。当然,autovacuum 最终会处理这个问题,但它可能会产生大量数据(很多 GB),我想确保我知道当我在这个非常大的表上进行大量更新时会发生什么。

我的一个解决方案是仅在提要发生某些重大更改(例如网站上出现新帖子)时才更新 TEXT 字段(存储 RSS 数据)。这意味着我可以避免进行更新,除非确实必须这样做。但是,我仍然想更新该表(以跟踪我最近执行 HTTP 请求的时间)。这将使用旧版本的行数据创建一个死元组。

如果 TEXT 数据实际上没有改变,会发生什么情况?当 UPDATE 创建死元组时,它还会复制 TEXT 数据吗?或者 TEXT 数据会保持不变,因为它没有更改并且存储在页外?

postgresql disk-space vacuum update autovacuum

6
推荐指数
1
解决办法
1919
查看次数

pg_stat_all_tables.last_autovacuum 什么时候更新?

我期待与我们的自动清理的问题,并试图了解last_autoanalyzelast_autovacuumpg_stat_all_tables

我理解 autovacuum 以增量方式工作,批量压缩和清理死元组,然后休眠片刻,等等。那么是什么last_autovacuum意思?是否有可能 autovacuum大部分时间都在工作,但时间戳可能永远不会更新(例如,因为无法删除元组)?

我看到的许多表的时间戳都很旧,尽管我相当确定我在某些表上观察到了一个正在运行的 autovacuum 线程。

编辑:如果我不清楚,我的问题是:确实last_autovacuum意味着......

  • 增量 autovacuum 进程最后完成此表上的大量工作并休眠的时间
  • autovacuum 过程一直工作到桌子最后的时间
  • 以上,但前提是没有无法删除的元组
  • 别的东西

postgresql autovacuum

5
推荐指数
1
解决办法
3057
查看次数

PostgreSQL autovacuum 忽略“非活动”表导致“事务 ID 环绕”

我有一个包含大量表(当前为 93k)的 PostgreSQL 数据库,并且我看到事务 ID 年龄威胁环绕的问题,因为对于长时间未写入的干净表,不会触发 autovacuum。

例如,我有一个表,我可以看出自“2018-09-19 10:30:43.625069+00”以来还没有被写入,这要归功于对该表的唯一插入总是设置一列updated_at(当前日期时间是“2018”) -10-04 23:58:25.545881+00'),有n_dead_tup = 0,并且有age(relfrozenxid) > 10000000

我有autovacuum_freeze_max_age = 10000000所以这应该意味着这个表将被自动清理,但相反我看到它超过了这一点,然后表的自动清理不会被触发(它目前处于age(relfrozenxid) > 70000000并且自动清理仍然没有触发。

我目前已将自动真空设置为最大程度地激进,但这种情况仍在发生。以下是自动清理设置:

track_counts = on
autovacuum = on
autovacuum_vacuum_cost_delay = 0
autovacuum_vacuum_cost_limit = 10000
autovacuum_vacuum_scale_factor = 0
autovacuum_vacuum_threshold = 1
autovacuum_freeze_max_age = 10000000
vacuum_freeze_min_age = 1000000
Run Code Online (Sandbox Code Playgroud)

(是的,我意识到autovacuum_vacuum_cost_limit这并不重要,autovacuum_vacuum_cost_delay因为0

目前,我被迫定期手动触发这些表的真空,以防止事情失控。不过,这感觉就像是黑客攻击。

有没有办法让 autovacuum 来清理这些表,或者相当于 autovacuum 忽略这些表的原因?

预计到达时间

如果有人来这里想看我处理这个问题的脚本,这里是:

#!/bin/bash -e
while true; do
  sleep 60 #just in case …
Run Code Online (Sandbox Code Playgroud)

postgresql autovacuum postgresql-10

5
推荐指数
0
解决办法
338
查看次数

autovacuum 会阻止 DROP 或 TRUNCATE 吗?

当 autovacuum 进程正在清理一个大表时,像 DROP 和 TRUNCATE 这样的查询会被阻塞直到清理完成吗?在文档中,它说

此外,标准形式的 VACUUM 可以与生产数据库操作并行运行。(诸如 SELECT、INSERT、UPDATE 和 DELETE 之类的命令将继续正常运行,尽管在清理表时您将无法使用诸如 ALTER TABLE 之类的命令来修改表的定义。)

但我想知道是否包括 DROP 或 TRUNCATE。

postgresql autovacuum

5
推荐指数
1
解决办法
726
查看次数

自动清理高写入、高更新和大多数读取的表类型

对于以下表来说,什么是好的自动真空设置(建议):

  • 高写表插入负载

    一天内插入 30-10,000 次。该表可以在没有负载的情况下闲置数周,但每周至少可以进行 3 次突发插入。

  • 高更新表

    它使用分区表数据,单次插入的大小是我的表大小的 3-8 倍。

  • 高写表

    单行仅更新一次,但一天内会突然更新唯一键,并且需要更新,可能是 30-10,000 个键更新。

  • 高读表

    大多数表都是高读取表,为我的数据仓库设置填充因子 80,容纳来自高更新表计算的表

我的删除每月进行一次并分批进行。与密钥相关的所有内容都会被删除或作为备份移动。

目前,对于高更新表,我的填充因子设置为 10-20 。

使用 TDS db.t3.large,但我在流量较低时切换到 db.t3.micro。

另外,设置填充因子真的很低会减慢选择速度吗?

postgresql maintenance autovacuum amazon-rds

5
推荐指数
1
解决办法
1985
查看次数