【问题标题】:Postgres crashes when selecting from view从视图中选择时 Postgres 崩溃
【发布时间】:2020-12-08 20:56:26
【问题描述】:

我在 Postgres 中有一个视图,其定义如下:

CREATE VIEW participant_data_view AS
SELECT participant_profile.*,
        "user".public_id, "user".created, "user".status, "user".region,"user".name, "user".email, "user".locale,
        (SELECT COUNT(id) FROM message_log WHERE message_log.target_id = "user".id AND message_log.type = 'diary') AS diary_reminder_count,
        (SELECT SUM(pills) FROM "order" WHERE "order".user_id = "user".id AND "order".status = 'complete') AS pills
FROM participant_profile
    JOIN "user" ON "user".id = participant_profile.id
;

视图创建工作正常。但是,当我查询视图 SELECT * FROM participant_data_view 时,postgres 崩溃了

10:24:46.345 WARN  HikariPool-1 - Connection org.postgresql.jdbc.PgConnection@172d19fe marked as broken because of SQLSTATE(08006), ErrorCode(0)                                                                            c.z.h.p.ProxyConnection
org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.

this question 向我建议,这可能是导致它崩溃的内部断言。

如果我从视图定义中删除 diary_reminder_count 字段,则选择工作正常。

我做错了什么?如何修复或更改视图以便以不同的方式查询相同的数据?

请注意,创建视图工作正常,它只会在查询时崩溃。

我尝试从 IntelliJ 查询控制台运行 explain (analyze) select * from participant_data_view;,它只返回

[2020-12-08 11:13:56] [08006] An I/O error occurred while sending to the backend.
[2020-12-08 11:13:56] java.io.EOFException

我使用psql 运行相同,它返回了

my-database=# explain (analyze) select * from participant_data_view;
server closed the connection unexpectedly
    This probably means the server terminated abnormally
    before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.

查看日志文件,它包含:

2020-12-08 10:24:01.383 CET [111] LOG:  server process (PID 89670) was terminated by signal 9: Killed: 9
2020-12-08 10:24:01.383 CET [111] DETAIL:  Failed process was running: select "public"."participant_data_view"."id", "public"."participant_data_view"."study_number", <snip many other fields>,
"public"."participant_data_view"."diary_reminder_count", "public"."participant
2020-12-08 10:24:01.383 CET [111] LOG:  terminating any other active server processes

【问题讨论】:

  • 这不是 PostgreSQL 错误消息。请尝试从psql 运行查询,并附上您在那里和数据库日志中看到的任何错误。
  • 您的连接池将此查询标记为“已崩溃”。我没有看到 Postgres 本身崩溃的任何证据。你能跑explain (analyze) select * from participant_data_view;吗? (注意analyze 使它运行查询但不返回结果)如果是,需要多长时间?也许连接池使用了查询超时,导致失败
  • 那么请检查 Postgres 服务器的日志文件
  • select * from message_log 工作正常吗?难道message_log 是一张外表?
  • @Stefanov.sm 该表上的查询工作正常,虽然我没有专门尝试过 select *

标签: postgresql


【解决方案1】:

Linux 内核内存不足杀手很可能会因为系统内存不足而终止您的查询。

要么限制数据库会话的数量(例如使用连接池),要么减少work_mem

在内核中设置vm.overcommit_memory = 2 并适当调整vm.overcommit_ratio 通常是个好主意。

【讨论】:

  • 这让我很惊讶,因为 Postgres 直接在我的开发机器上运行。视图中有什么可以解释这么多内存使用的吗?我认为简单的计数和/或总和不会那么昂贵。目前该视图应该只有大约 1200 行。
  • 除了内核之外,还有谁会杀死您开发机器上的后端?在这种情况下,结果行的数量并不重要。您可以查看EXPLAIN 输出,看看是否有更大的散列、位图或排序。
  • 这是问题的一部分:解释查询也会崩溃,如问题中所述
  • 我说的是EXPLAIN,没有ANALYZE
  • 我在 Kubernetes 上看到了这个 - 日志中没有任何提示,但是增加内存限额有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多