【问题标题】:PostgreSQL: Backend processes are active for a long timePostgreSQL:后端进程长时间处于活动状态
【发布时间】:2018-12-20 13:32:48
【问题描述】:

现在我遇到了一个很大的障碍。

我使用 PostgreSQL 10 及其新的表分区。

当我通过pg_stat_activity 检查后端进程时,有时许多查询不会返回,而当时许多后端进程都是active。 首先,我认为这些进程只是在等待lock,但这些事务只包含SELECT 语句,而另一个后端不使用任何需要ACCESS EXCLUSIVE 锁定的查询。而这些只包含SELECT 语句的查询在计划上是没有问题的。通常这些都很好用。并且计算机资源(CPU、内存、IO、网络)也没有问题。因此,这些交易不应发生冲突。而且我通过pg_lockspg_blocking_pids() 仔细检查了这些事务的锁,最后我找不到任何使查询变慢的锁。许多活动的后端仅保留ACCESS SHARE,因为它们仅使用SELECT。 现在我认为这些现象不是锁引起的,而是与新表分区有关。

那么,为什么许多后端处于活动状态? 有人可以帮我吗? 任何 cmets 都受到高度赞赏。 打击图是pg_stat_activity 结果的一部分。 如果您想了解更多信息,请告诉我。

编辑

我的查询不处理大数据。返回类型是这样的:

uuid UUID
,number BIGINT
,title TEXT
,type1 TEXT
,data_json JSONB
,type2 TEXT
,uuid_array UUID[]
,count BIGINT

因为它有JSONB 列,我无法计算出确切的值,但它不是很大的JSON。 通常这些查询都比较快(大约1.5s),所以绝对没有问题,但是当其他进程工作时,就会出现这种现象。 如果统计信息有误,查询总是很慢。

EDIT2

这是统计数据。有将近 100 个连接,所以我无法显示所有统计信息。

【问题讨论】:

  • 1) 当您的查询从表中返回大量数据并且您在查询工具上显示该数据而不是插入其他表或进行任何其他操作时,有时会发生这种情况。您不应该查询以显示大数据 2) 或者可能是因为缺少统计信息。在那张桌子上分析和吸尘。你能发布查询和它返回的数据量吗
  • 你能发布完整的统计数据吗?请检查拥有该进程的 pg_stat_activity 下的应用程序名称。类似,application_name | PostgreSQL JDBC 驱动程序 client_addr | 127.0.0.1
  • 在生产中遇到类似问题,有时活动查询的数量会达到 ±200。在我的情况下,所有查询都是不同的并且正在查询不同的表,但是,与您的情况相同,没有被任何写入锁定。在调查过程中,我们尝试使用work_memshared_buffers,它确实有帮助。在你的情况下,我会走同样的路。我们正在通过 DataDog 监控我们的数据库服务器,如果您有类似的监控可用,您应该能够调整配置以帮助解决您的问题。我们使用的是 9.3 和非分区表。
  • 如果我们的情况相似,您很可能遇到了 Postgres 队列重新分配内存给进程的问题。只是我的猜测。我真的很想知道你将如何解决这个问题,所以一定要回帖。
  • @Mohamed Anees A 见 EDIT2。我展示了,但你为什么要看到它?我不明白你为什么要检查 application_names。

标签: postgresql


【解决方案1】:

对我来说,这看起来像是应用程序问题,而不是 postresql 的问题。 active 状态表示您的事务仍未提交。

那么为什么您的应用程序可能无法将commit 发送到数据库?

尝试查看您的应用程序代码中何时使用open transactionread datacommit transactionrollback transaction

编辑: 顺便说一句,请务必在问题出现之前以及您的查询开始挂起时检查资源使用情况。尝试运行topiotop 来检查postgres 是否真的开始吃掉你的cpudisk,当问题出现时会发疯。如果没有,我会建议在您的应用程序中查找问题。

【讨论】:

    【解决方案2】:

    谢谢大家。

    我终于解决了这个问题。 我注意到后端进程持有太多锁。所以,当我执行查询SELECT COUNT(*) FROM pg_locks WHERE pid = <pid>时,结果大约是10000。 locks_per_transactions的参数是64,max_connections的参数是800左右。 所以,如果持有很多锁的查询数量很大,就会出现内存不足的情况(有兴趣的可以查看PostgreSQL内部共享内存的计算代码)。 当我执行SELECT * FROM (partitioned table) 之类的查询时,导致了太多的锁。想象一下,你有一个表foo,它是分区的,表的数量是1000。然后你可以执行SELECT * FROM foo WHERE partion_id = <id>,后端进程将持有大约1000个表锁(和索引锁)。所以,我将查询从SELECT * FROM foo WHERE partition_id = <id> 更改为SELECT * FROM foo_(partitioned_id)。结果,问题看起来解决了。

    【讨论】:

      【解决方案3】:

      你说

      有时很多查询都没有返回 ...但是当其他进程工作时,这种现象就会发生。如果统计 信息有误,查询总是很慢。

      当直接连接到 Postgres 实例并运行您需要的查询时,或者从应用程序运行查询时,它们不会返回/速度很慢?正在运行的后端进程,你能用pg_terminate_backend($PID) 成功杀死它们还是有问题?要排除语句本身的问题,请确保将 statement_timeout 设置为合理的数量以终止长时间运行的查询。排除这之后,您可能会遇到应用程序挂起并且不允许来自 PostgreSQL 的 send 调用完成的情况。为了避免这种情况,如果您能够(取决于操作系统)可以调整保持活动时间:@​​987654321@(默认为 2 小时)

      如果使用其中任何一种方法可以更深入地了解您的问题,请告诉我们。

      【讨论】:

        【解决方案4】:

        对于迟到的帖子感到抱歉,正如@Konstantin 指出的那样,这可能是因为您的应用程序(这就是我要求您提供 EDIT2 的原因)。添加一些摘录,

        • table partition 对这些锁没有影响,这是一个完全不同的概念,在您的情况下不会持有锁。
        • 在您的应用程序中,检查close()read() 之后的连接是否正确并且是否在 finally 块中(从Java 角度来看)。我不确定您的应用层。
        • 检查最近是否错误地写入了 SELECT..FOR UPDATE 或任何类似语句,从而导致此问题。
        • 检查最近是否有任何表的大小增加并且列未编入索引。这是选择语句运行几分钟的非常重要且频繁的原因。我还建议在您的应用程序中使用timeouts 来选择语句。 https://www.postgresql.org/docs/9.5/gin-intro.html 这可以让您领先一步。
        • 对我来说,另一件可疑的事情是 JSONB 列,也许您的 Jsonb 值很长,或者即使不需要,查询也不必要地选择 JSONB 值?
        • 最后,如果您不需要 Jsonb 数据类型的一些特殊功能,那么您可以使用更快的 JSON 数据类型(神奇的最大值,有时是 50 倍!)

        【讨论】:

          【解决方案5】:

          看起来池连接没有正确关闭,一些查询可能需要很长时间才能回复。正如其他答案所指出的,这是应用程序的问题,可能是连接泄漏。最有可能的是,由于一些已挂起和未解决的事务的挂起交易,导致许多未关闭的事务。

          另外,PostgreSQL一般有一个或多个“helper”进程,如stats collectorbackground writerautovaccum daemonwalsender等,所有这些都显示为“postgres”实例。

          我建议您检查一下您启动了queries 的代码的哪一部分。尝试DRY 在应用程序之外运行您的查询并获得一些benchmarking 的查询性能。

          其次,如果不是全部,您可以为某些查询保留一些 超时

          第三,你可以在某些超时后使用kill the idle transactions

          SET SESSION idle_in_transaction_session_timeout = '5min';
          

          我希望它可能会奏效。干杯!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-05-13
            • 1970-01-01
            • 2016-03-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多