我正在目睹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)如何在不遇到“超出共享内存”错误的情况下制作大量视图?
答案 0 :(得分:2)
1)即使我制作了临时视图和我的主要方法(我也是 正在创建视图)优雅地退出,为什么视图仍然存在 目前在db?
临时对象在会话期间(不仅仅是事务)持续存在。您必须关闭会话或删除对象以从逻辑上将其从系统目录中删除。在物理上,一个死元组留在VACUUM FULL
之后或重用......)。
即使临时对象在(非临时)系统目录中也有条目。 (这就是创建临时表/视图会触发磁盘写入的原因。)因此,查询SELECT count(*) from pg_views
会从任何会话产生相同的数字,只要拥有的会话没有终止。