重复临时 table 创作导致 pg_attribute 膨胀
Bloating of pg_attribute caused by repetitive temporary table creations
我有一个进程每天创建数千个临时 table 以将数据导入系统。
它使用的形式是:
create temp table if not exists test_table_temp as
select * from test_table where 1=0;
这很快在 pg_attribute 中创建了 很多 死行,因为它不断地创建大量新列并在不久之后删除这些 tables。我在其他地方看到建议使用 on commit delete rows
的解决方案。但是,这似乎也没有达到预期的效果。
要测试以上内容,您可以在测试数据库上创建两个单独的会话。在其中一个中,检查:
select count(*)
from pg_catalog.pg_attribute;
并记下 n_dead_tup 的值来自:
select n_dead_tup
from pg_stat_sys_tables
where relname = 'pg_attribute';
在另一个上,创建一个临时文件 table(需要另一个 table 到 select):
create temp table if not exists test_table_temp on commit delete rows as
select * from test_table where 1=0;
pg_attribute
的计数查询立即上升,甚至在我们到达提交之前。关闭临时 table 创建会话后,pg_attribute
值下降,但 n_dead_tup
上升,表明仍然需要清理。
我想我真正的问题是我是否遗漏了上面的内容,或者是处理这个问题的唯一方法是积极地吸尘并承受随之而来的性能损失吗?
提前感谢您的回复。
不对,您理解正确。
您要么需要使 autovacuum 更具侵略性,要么需要使用更少的临时 tables。
不幸的是,您无法更改目录上的存储参数 table – 至少不能以升级后仍然存在的受支持方式更改 – 因此您必须对整个集群进行更改。
我有一个进程每天创建数千个临时 table 以将数据导入系统。
它使用的形式是:
create temp table if not exists test_table_temp as
select * from test_table where 1=0;
这很快在 pg_attribute 中创建了 很多 死行,因为它不断地创建大量新列并在不久之后删除这些 tables。我在其他地方看到建议使用 on commit delete rows
的解决方案。但是,这似乎也没有达到预期的效果。
要测试以上内容,您可以在测试数据库上创建两个单独的会话。在其中一个中,检查:
select count(*)
from pg_catalog.pg_attribute;
并记下 n_dead_tup 的值来自:
select n_dead_tup
from pg_stat_sys_tables
where relname = 'pg_attribute';
在另一个上,创建一个临时文件 table(需要另一个 table 到 select):
create temp table if not exists test_table_temp on commit delete rows as
select * from test_table where 1=0;
pg_attribute
的计数查询立即上升,甚至在我们到达提交之前。关闭临时 table 创建会话后,pg_attribute
值下降,但 n_dead_tup
上升,表明仍然需要清理。
我想我真正的问题是我是否遗漏了上面的内容,或者是处理这个问题的唯一方法是积极地吸尘并承受随之而来的性能损失吗?
提前感谢您的回复。
不对,您理解正确。
您要么需要使 autovacuum 更具侵略性,要么需要使用更少的临时 tables。
不幸的是,您无法更改目录上的存储参数 table – 至少不能以升级后仍然存在的受支持方式更改 – 因此您必须对整个集群进行更改。