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:
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.
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.
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
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!
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.
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.
@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;