PostgreSQL:创建大量视图

时间:2012-08-22 19:09:16

标签: postgresql transactions views

我正在目睹Postgres的一种奇怪行为。这就是我在做的事情:

我尝试创建10,000个临时视图,如下所示

psqlStatement.executeUpdate("CREATE OR REPLACE TEMP VIEW " + symbols.get(i) + " AS SELECT * from persons;"); 

创建了大约9000个视图后,我开始收到“共享内存中的错误。提示:您可能需要增加max_locks_per_transaction”

我接受了提示并将值从64(默认值)更改为postgresql.conf文件中的100。更改此值后,我无法启动Postgres服务器。如果我将值更改回64或65,则服务器启动。

为了进一步调查此问题,我创建了8,000个成功的视图,而不是创建10,000个视图。我启动了Postgres控制台并编写了查询以显示所有视图,我得到了相同的错误(共享内存。提示:你可能......)再次

总而言之,我看到了三件奇怪的事情:

1)即使我制作了临时视图,我的主要方法(我正在创建视图)也会优雅地退出,为什么视图仍然存在于数据库中?我做了

SELECT count(*) from pg_views
WHERE schemaname NOT IN('information_schema', 'pg_catalog'); 

它返回了8,000。

2)如果max_locks_per_transaction的值高于64(根据提示),为什么Postgres服务器不会启动?

3)如何在不遇到“超出共享内存”错误的情况下制作大量视图?

1 个答案:

答案 0 :(得分:2)

  

1)即使我制作了临时视图和我的主要方法(我也是   正在创建视图)优雅地退出,为什么视图仍然存在   目前在db?

临时对象在会话期间(不仅仅是事务)持续存在。您必须关闭会话或删除对象以从逻辑上将其从系统目录中删除。在物理上,一个死元组留在VACUUM FULL之后或重用......)。

即使临时对象在(非临时)系统目录中也有条目。 (这就是创建临时表/视图会触发磁盘写入的原因。)因此,查询SELECT count(*) from pg_views会从任何会话产生相同的数字,只要拥有的会话没有终止。