从pg_stat_activity收集postgres pids /后端会在一个会话中返回常量结果

时间:2018-06-06 10:16:26

标签: python postgresql sqlalchemy

在具有隔离级别view-port的一个会话中,READ_COMMITTED的活动pid列表仅收集一次,下次尝试将返回相同的结果。有谁能解释原因?

重现这种现象的脚本:

pg_stat_activity

我正在使用:

#!/usr/bin/env python

import time

from sqlalchemy.engine import create_engine
from sqlalchemy.orm.session import sessionmaker
from sqlalchemy.pool import NullPool

pg_uri = 'postgresql://test:test@localhost:5432/test'


def get_session():
    bind = create_engine(pg_uri, poolclass=NullPool, echo=False, isolation_level="READ_COMMITTED")
    session_class = sessionmaker(bind=bind)
    return session_class()

def pg_sleep():
    get_session().execute('select pg_sleep(3)')


def show_backends(session, prefix):
    backends = session.execute("SELECT pid, query FROM pg_stat_activity where state = 'active';").fetchall()
    print ("%s found processes:" % prefix)
    for backend in backends:
        print("%s: %s %s" % (prefix, backend[0], backend[1][:32]))


def spawn_backend():
    import threading
    print("spawning backend")
    threading.Thread(None, target=pg_sleep).start()
    show_backends(get_session(), 'thread')


session = get_session()
for tries in range(3):
   spawn_backend()
   time.sleep(1)
   show_backends(session, '-main-')

1 个答案:

答案 0 :(得分:2)

关于monitoring stats的文档说:

  

另一个重要的一点是,当要求服务器进程显示任何这些统计信息时,它首先获取收集器进程发出的最新报告,然后继续将此快照用于所有统计视图和函数,直到结束它目前的交易。因此,只要您继续当前事务,统计信息就会显示静态信息。类似地,当在事务中首次请求任何此类信息时,收集关于所有会话的当前查询的信息,并且将在整个事务中显示相同的信息。这是一个功能,而不是一个错误,因为它允许您对统计信息执行多个查询并关联结果,而不必担心数字在您下面发生变化。但是,如果要查看每个查询的新结果,请确保在任何事务块之外执行查询。或者,您可以调用pg_stat_clear_snapshot(),它将丢弃当前事务的统计信息快照(如果有)。下次使用统计信息将导致获取新的快照。

请考虑在代码中使用pg_stat_clear_snapshot