如何列出所有活动会话的所有预处理语句?

9

我知道可以通过从pg_prepared_statements表中选择所有行来列出当前会话的所有准备好的语句,但是有没有办法查看所有活动会话的所有准备好的语句?我认为我正在寻找类似于管理员功能的东西,但是在文档中找不到任何类似的内容。

2个回答

8
不行。据我所知,准备好的语句是局限于一个后端的;其他后端不知道它们的存在。您需要修改服务器以添加额外的进程间通信,以允许一个后端询问其他后端有关准备好的语句的信息。
最初,后端似乎共享相同的pg_prepared_statements 表存储,如下所示:
SELECT relfilenode FROM pg_class WHERE  relname = 'pg_prepared_statements';

从不同的后端返回相同的relfilenode。我感到惊讶,因为我认为准备好的语句在磁盘上没有存在。如果它们在磁盘上,我想你可以使用pageinspect contrib模块中的函数来读取原始元组或表页。可见性会是一个问题;你怎么知道与死亡/终止的后端相关的内容以及哪些是有效的?

我尝试了一下,发现pg_prepared_statements实际上是一个视图:

regress=# SELECT * FROM heap_page_items(get_raw_page('pg_prepared_statements', 1));
ERROR:  cannot get raw page from view "pg_prepared_statements"

具体来说,涉及到pg_prepared_statement()函数的一些视图。因此没有什么需要检查的。这是后端内部。

这似乎是那种“…但你为什么要这样做?”的问题,通常这意味着有人在询问他们为解决实际问题而设想的解决方案,而不是询问他们的真正问题。

那么:为什么你想这样做?你试图解决什么实际问题?


是的,你说得对,我正在试图缩小一个问题,但我不确定如何用问题的形式来概括。我认为这可能与缓存的预处理语句有关,返回了具有之前“更新”之前存在的值的行。 - Igor Zinov'yev
1
@IgorZinov'yev,准备好的语句与查询旧数据极不相关。准备好的语句没有结果缓存或数据缓存,只有计划缓存。我唯一能想象到可能发生这种情况的方式是,如果您在表继承结构中删除了一个分区,并且准备好的语句的计划没有被清除,但Pg非常小心地跟踪准备好的语句的依赖关系,以防止这种情况发生。 - Craig Ringer
@IgorZinov'yev 你可能需要研究一下事务隔离(你是否在READ COMMITEDSERIALIZABLE隔离级别?),事务标记(你的交易开始和结束的位置是否符合预期),等等。 - Craig Ringer
你说得对,这与预处理语句没有任何关系。它与不正确的元标记放置有关,导致浏览器页面重新加载,从而在页面上使用无效的缓存数据。我偶然发现了这个问题,可以说我非常惊讶。 - Igor Zinov'yev

0

.

你真正想要解决的问题是什么?

我有一个分区表 xxx.yyy

问题在于当我尝试执行:

VACUUM FULL VERBOSE xxx.yyy_69;

我看到:

INFO:  "yyy_69": found 0 removable, 3648431 nonremovable row versions in 72968 pages
DETAIL:  0 dead row versions cannot be removed yet.

据我所知,可能有三个原因:
  1. 长时间运行的事务(但我已经执行了:ALTER all_application_users with nologin; SELECT pg_terminate_backend(all_pids)
  2. 废弃的复制槽(我不使用复制槽)
  3. 孤立的预处理事务
(而且我认为这就是问题所在)
只有在执行以下操作后问题才得到解决: pg_ctl restart VACUUM FULL VERBOSE xxx.yyy_69; ALTER all_application_users with login;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接