Query causando 400% de Carga na CPU

Temos tido sobrecarga de CPU recentemente.
Conseguimos identificar que é uma consulta que fica rodando simultaneamente por horas (veja abaixo).
A tarefa em execução é o postmaster - assim que todos são encerrados, a CPU é reduzida até ser reconstruída a cada cinco minutos.

SELECT “users”.“id”, ARRAY_AGG(ARRAY [uccm.id, c_msg.id]) AS memberships_with_unread_messages
FROM “users”
         INNER JOIN “user_options” ON “user_options”.“user_id” = “users”.“id”
         INNER JOIN user_chat_channel_memberships uccm ON uccm.user_id = users.id
         INNER JOIN chat_channels cc ON cc.id = uccm.chat_channel_id
         INNER JOIN chat_messages c_msg ON c_msg.chat_channel_id = uccm.chat_channel_id
         LEFT OUTER JOIN chat_mentions c_mentions ON c_mentions.chat_message_id = c_msg.id
WHERE “user_options”.“chat_enabled” = TRUE
  AND “user_options”.“chat_email_frequency” = 1
  AND (users.last_seen_at < ‘2023 - 11 - 15 09:54:26.931723’)
  AND (c_msg.deleted_at IS NULL AND c_msg.user_id <> users.id)
  AND (c_msg.created_at > ‘2023 - 11 - 08 10:09:26.931848’)
  AND ((uccm.last_read_message_id IS NULL OR c_msg.id > uccm.last_read_message_id) AND
       (uccm.last_unread_mention_when_emailed_id IS NULL OR c_msg.id > uccm.last_unread_mention_when_emailed_id) AND
       (uccm.user_id = c_mentions.user_id AND uccm.following IS true AND
        cc.chatable_type = ‘Category’

Alguém pode ajudar ou sugerir uma solução?

Mais informações:

  • rodando 3.2.0.beta4-dev, mas isso vem acontecendo há pelo menos alguns meses
  • Aqui está uma lista de plugins que temos instalados:

Obrigado!

2 curtidas

@andrei trabalhou na otimização de consultas de chat recentemente, isso ainda acontece após a atualização para a versão mais recente?

4 curtidas

Trabalhei em outra consulta semelhante e a correção foi local para essa consulta, então provavelmente não ajudará aqui. Ainda assim, vale a pena atualizar para a versão mais recente, pode haver outras otimizações.

2 curtidas

Estamos no mais recente, de fato.

Acho que foi um problema de chat com a consulta. Há algo que possamos ajustar nas configurações para corrigir isso?

1 curtida

Tivemos um cliente que ativou menções @all no chat, com dois canais de 16 mil usuários. Foi divertido!
Após 19 menções a todos, eles rapidamente desativaram novamente. 12 horas depois, o sistema deles (robusto) ainda estava com alta carga de CPU.

O problema foi resolvido limpando os 320 mil registros ofensivos da tabela de menções

delete from chat_mentions
where chat_message_id in (
  (select chat_message_id
   from chat_mentions
   group by chat_message_id having count(*) > 100)
);

mas ainda estávamos intrigados por que isso estava causando tantos problemas.
Houve um número de instâncias desta consulta aqui ainda em execução.

Como as linhas já haviam sumido, um explain não deu bons resultados, mas é claro que estava fazendo um trabalho pesado. Todos os índices estão no lugar.

1 curtida

Acho que alguém mencionou que a consulta também foi intensiva ontem:

2 curtidas

Obrigado - eu deveria aprender a pesquisar neste fórum de forma mais eficaz.

1 curtida

Isso não resolveu para nós.

Também vimos mensagens de chat desaparecerem por até alguns minutos antes de reaparecerem.

Geralmente, acho que há muito a melhorar no chat, embora eu goste totalmente da direção que ele está tomando. Minha principal preocupação é como um chat pode essencialmente causar uma sobrecarga que não para. Desativamos a capacidade de mencionar, e isso também não funcionou.

Existe alguma maneira de impedir que a consulta que mencionei volte? @andrei @JammyDodger

Obrigado antecipadamente.

Olá @sok777 , obrigado por acompanhar — temos alguns engenheiros analisando isso e entraremos em contato com você aqui assim que tivermos uma atualização. Agradecemos sua paciência enquanto isso!

2 curtidas

Um truque que funciona bem é Administrador - Personalizar - Palavras Monitoradas e adicionar ambas as menções à lista “Censurar”.

então ‘all’ e ‘here’ com um prefixo de @?

Obrigado!

1 curtida

Ótimo. Obrigado!

1 curtida

Uma atualização rápida @lindsey @RGJ

Tivemos uma mensagem com @all que excluímos. No entanto, isso não resolveu o problema. A consulta continua voltando a cada 5 minutos e está demorando muito, a ponto de haver uma fila de muitas outras consultas.
Assim que desativamos o chat, a carga da CPU caiu para 15%. Loucura.

Você precisa entrar no banco de dados e remover os registros de menções

psql: delete from chat_mentions where chat_message_id = X
onde X é o ID da mensagem que você removeu.

Uma consulta mais genérica é descrita na minha mensagem aqui, ajuste o número como achar melhor.

1 curtida

Sim, já tentamos isso.

Para referência, estas são as nossas estatísticas:

users: 239251
chat_channels: 2864
chat_drafts: 205
chat_mentions: 155527 ->7500~
chat_messages: 390453
chat_threads: 25131
chat_message_reactions: 5993
user_chat_channel_memberships: 158480

1 curtida

A única razão pela qual essa consulta pode demorar é devido às muitas entradas na tabela chat_mentions. Você já tentou a consulta genérica que postei? Talvez não seja @all, mas outro grupo grande que está sendo mencionado.

A consulta problemática verifica todas as menções de chats nos últimos 7 dias.

Você também deve encerrar todas as instâncias existentes da consulta.

Sim, nós os matamos, mas eles continuam voltando.
Verificamos todas as menções acima de 100 e não encontramos nenhuma. Não tenho certeza por que mais isso aconteceria.
Parece-me que há um problema fundamental com a consulta, mas posso estar errado.

1 curtida

Esta consulta provavelmente é lenta mesmo com uma pequena quantidade de menções. Trabalharei para corrigi-la.

2 curtidas

Ótimo. Feliz em continuar a apoiar a partir do nosso caso de uso!

2 curtidas

@sok777 Preciso de um pouco da sua ajuda com isto. Gostaria de ver o plano de consulta que o Postgres usa no seu site. Poderia, por favor, executar isto na sua base de dados e partilhar os resultados:

EXPLAIN VERBOSE SELECT "users"."id", ARRAY_AGG(ARRAY [uccm.id, c_msg.id]) AS memberships_with_unread_messages
FROM "users"
         INNER JOIN "user_options" ON "user_options"."user_id" = "users"."id"
         INNER JOIN "group_users" ON "group_users"."user_id" = "users"."id"
         INNER JOIN "groups" ON "groups"."id" = "group_users"."group_id"
         INNER JOIN user_chat_channel_memberships uccm ON uccm.user_id = users.id
         INNER JOIN chat_channels cc ON cc.id = uccm.chat_channel_id
         INNER JOIN chat_messages c_msg ON c_msg.chat_channel_id = uccm.chat_channel_id
         LEFT OUTER JOIN chat_mentions c_mentions ON c_mentions.chat_message_id = c_msg.id
WHERE "user_options"."chat_enabled" = TRUE
  AND "user_options"."chat_email_frequency" = 1
  AND (users.last_seen_at < '2023-11-27 08:00:00.0000000')
  AND (c_msg.deleted_at IS NULL AND c_msg.user_id <> users.id)
  AND (c_msg.created_at > '2023-11-20 08:00:00.0000000')
  AND ((uccm.last_read_message_id IS NULL OR c_msg.id > uccm.last_read_message_id) AND
       (uccm.last_unread_mention_when_emailed_id IS NULL OR c_msg.id > uccm.last_unread_mention_when_emailed_id) AND
       (
               (uccm.user_id = c_mentions.user_id AND uccm.following IS true AND cc.chatable_type = 'Category') OR
               (cc.chatable_type = 'DirectMessage')
           )
    )
GROUP BY users.id, uccm.user_id
ORDER BY "users"."id" ASC
LIMIT 1000;
1 curtida