Postgres가 대규모 데이터베이스에서 CPU 100% 사용, Discourse 2.7.7

안녕하세요,

저희는 매우 많은 사용자를 보유한 Docker 기반 Discourse 2.7.7을 운영 중입니다. 2.4.2에서 2.7.7로 업그레이드한 후, 일부 Postgres 프로세스가 CPU 100%에서 멈춰 있는 현상을 겪고 있습니다. 추가 조사를 통해 이러한 쿼리가 문제를 일으키는 것으로 파악되었습니다:

discourse_prod=# select pid, datid, query from pg_stat_activity WHERE pid = '244906';
  pid   |  datid  |                         query
--------+---------+-------------------------------------------------------
 244906 | 2068583 | DELETE FROM user_badges                              +
        |         |   WHERE id IN (                                      +
        |         |     SELECT ub.id                                     +
        |         |     FROM user_badges ub                              +
        |         |     LEFT JOIN (                                      +
        |         |       SELECT id user_id, current_timestamp granted_at+
        |         | FROM users                                           +
        |         | WHERE id  IN (                                       +
        |         |        SELECT p1.user_id                             +
        |         |        FROM post_custom_fields pc                    +
        |         |        JOIN badge_posts p1 ON p1.id = pc.post_id     +
        |         |        JOIN topics t1 ON p1.topic_id = t1.id         +
        |         |        WHERE p1.user_id <> t1.user_id AND            +
        |         |                     name = 'is_accepted_answer' AND  +
        |         |             p1.user_id IN (                          +
        |         |                    SELECT user_id                    +
        |         |                    FROM posts                        +
        |         |                    WHERE TRUE OR  p1.id IN (-1)      +
        |         |             )                                        +
        |         |         GROUP BY p1.user_id                          +
        |         |         HAVING COUNT(*) > 9                          +
        |         | )                                                    +
        |         |     ) q ON q.user_id = ub.user_id                    +
        |         |                                                      +
        |         |     WHERE ub.badge_id = 103 AND q.user_id IS NULL    +
        |         |   )                                                  +
        |         |
(1 row)

아래의 쿼리를 발견했는데, 이것이 막대한 오버헤드를 유발할 것 같은데 맞나요?

        |         |                    SELECT user_id                    +
        |         |                    FROM posts                        +
        |         |                    WHERE TRUE OR  p1.id IN (-1)      +

이 문제에 대해 어떤 조언이 있을까요?
추가 정보가 필요하시면 알려주세요.

감사합니다,
Daniel.

이 쿼리는 Jobs::BadgeGrant에서 온 것으로 보입니다.

문제가 사용자 배지 내의 사용자 정의 SQL 쿼리 때문이라는 것을 확인했습니다. 따라서 이는 업스트림 문제가 아닙니다. 감사합니다.

PostgreSQL 13 업데이트에 설명된 대로 VACUUM과 재인덱싱을 수행해야 할 것으로 보입니다.