1

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

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

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

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

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

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

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

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

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

它返回了 8,000。

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

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

4

1 回答 1

2

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

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

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

于 2012-08-22T19:53:42.800 回答