我需要在 PostgreSQL 中手动 VACUUM 临时表吗?
Do I need to manually VACUUM temporary tables in PostgreSQL?
假设我有一个应用程序服务器:
- 使用连接池(允许空闲连接的数量相对较多),
- 可以 运行 几个月,并且
- 大量使用临时表(未在
COMMIT
上 DROP
)。
上面的意思是我可能有N"eternal"个数据库会话"holding"N个临时表,这只有在服务器重新启动时才会被删除。
我很清楚 autovacuum 守护程序无法访问那些临时表。
我的问题是,如果我经常从临时表中创建 INSERT
和 DELETE
,并且这些表应该 "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" 它们。因此我们后来改用普通表。
假设我有一个应用程序服务器:
- 使用连接池(允许空闲连接的数量相对较多),
- 可以 运行 几个月,并且
- 大量使用临时表(未在
COMMIT
上DROP
)。
上面的意思是我可能有N"eternal"个数据库会话"holding"N个临时表,这只有在服务器重新启动时才会被删除。
我很清楚 autovacuum 守护程序无法访问那些临时表。
我的问题是,如果我经常从临时表中创建 INSERT
和 DELETE
,并且这些表应该 "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" 它们。因此我们后来改用普通表。