我需要在 PostgreSQL 中手动 VACUUM 临时表吗?

Do I need to manually VACUUM temporary tables in PostgreSQL?

假设我有一个应用程序服务器:

上面的意思是我可能有N"eternal"个数据库会话"holding"N个临时表,这只有在服务器重新启动时才会被删除。

我很清楚 autovacuum 守护程序无法访问那些临时表。

我的问题是,如果我经常从临时表中创建 INSERTDELETE,并且这些表应该 "live" 很长时间,那么我是否需要在删除后手动 VACUUM 这些表,或者一个手动 ANALYZE 就足够了?

目前,如果我执行

select
  n_tup_del,
  n_live_tup,
  n_dead_tup,
  n_mod_since_analyze,
  vacuum_count,
  analyze_count
from
  pg_stat_user_tables
where
  relname = '...'
order by
  n_dead_tup desc;

我看到 vacuum_count 总是零:

n_tup_del   n_live_tup  n_dead_tup  n_mod_since_analyze vacuum_count    analyze_count
64      3       64      0           0       16
50      1       50      26          0       3
28      1       28      2           0       5
7       1       7       4           0       4
3       1       3       2           0       4
1       6       1       8           0       2
0       0       0       0           0       0

这可能意味着确实需要手动 VACUUM

https://www.postgresql.org/docs/current/static/sql-commands.html

ANALYZE — collect statistics about a database

VACUUM — garbage-collect and optionally analyze a database

vacuum 也可以选择分析。因此,如果您想要 - 最新统计数据 - 只需 analyze。如果要 "recover" 未使用的行,则 vacuum。如果两个都想要,请使用 vacuum analyze

我们有一个应用程序 运行 超过 24 小时,使用了很多长期存在的非常繁重的更新临时表,我们对它们使用了 ANALYZE。但是 VACUUM 有一个问题——如果你尝试在函数中使用你会得到一个错误:

ERROR:  VACUUM cannot be executed from a function or multi-command string
CONTEXT:  SQL statement "vacuum xxxxxx"
PL/pgSQL function inline_code_block line 4 at SQL statement
SQL state: 25001

但后来我们发现,临时表实际上并没有那么有利,至少对我们的应用程序来说是这样。从技术上讲,它们是在所谓的临时表空间(pg_default 或者您可以在 postgresql.conf 文件中设置它)中作为数据文件存在于磁盘上的普通表。但他们只使用所谓的 temp_buffers - 他们没有加载到 shared_buffers。所以你必须正确设置 temp_buffers 并更多地依赖 Linux 缓存。正如您已经提到的 - autovacuum 守护进程 "does not see" 它们。因此我们后来改用普通表。