Ao trabalhar em um contêiner local onde importei dados de um fórum SMF2 com mais de 20 anos de atividade, me deparei com um bug crítico em Topic.reset_all_highest.
Após a importação dos dados, meu banco de dados mostra cerca de 60 mil tópicos regulares e cerca de 400 mil tópicos de mensagens privadas, e as consultas em Topic.reset_all_highest causam algum tipo de crescimento geométrico das linhas, resultando na falta de espaço em disco (com 120 GB livres para começar).
Atualmente, estou tentando dividir as consultas em blocos gerenciáveis e executá-las diretamente no Postgres, mas isso é, obviamente, subótimo (e não tenho certeza se funciona e resulta nos dados corretos).
Tentei ver se mais alguém teve esse tipo de problema, mas não encontrei nada, então estou imaginando se isso pode estar de alguma forma relacionado à minha própria configuração - estou usando a versão Docker mais recente, para constar.
Fiz uma importação de tamanho modesto recentemente que também está travada aparentemente indefinidamente em Topic.reset_all_highest e tive que encerrar a consulta no Postgres para continuar. Eu não tive esse problema antes e pensei que talvez fosse apenas que meu servidor postgres estava sobrecarregado (ele tem vários sites conectados).
Meu próximo passo foi mudar para outro servidor postgres, mas ainda não tive tempo para isso.
Após os dois primeiros trechos do meu experimento de “consulta dividida” terem corrido bem (X e Y para tópicos públicos), tentei com o Z, e ele travou - ou seja, a consulta estava ativa de acordo com a atividade do postgres, e top mostrava o processo rodando a 100%.
Então olhei novamente para o SQL e encontrei o problema: ambas as consultas terminam assim
WHERE
topics.archetype <> 'private_message' AND
X.topic_id = topics.id AND
Y.topic_id = topics.id AND
(
topics.highest_staff_post_number <> X.highest_post_number OR
topics.highest_post_number <> Y.highest_post_number OR
topics.last_posted_at <> Y.last_posted_at OR
topics.posts_count <> Y.posts_count OR
topics.word_count <> Z.word_count
)
(o outro tem ‘private_message’ como arquétipo, é claro)
O que significa que a consulta está perdendo
Z.topic_id = topics.id - o que causa o aumento geométrico todo.
Alterar a cláusula WHERE das consultas para
WHERE
topics.archetype <> 'private_message' AND
X.topic_id = topics.id AND
Y.topic_id = topics.id AND
Z.topic_id = topics.id AND
(
topics.highest_staff_post_number <> X.highest_post_number OR
topics.highest_post_number <> Y.highest_post_number OR
topics.last_posted_at <> Y.last_posted_at OR
topics.posts_count <> Y.posts_count OR
topics.word_count <> Z.word_count
)
resolveu o problema para mim.
Devo abrir um PR?
Eu acho que sim. Se você conseguir encontrar um commit que quebrou isso, seria ainda mais convincente.
Abri um PR para isso, com algumas limitações infelizes (ou seja, não consigo imaginar como testar essa alteração).
Esta alteração parece correta, mesclando-a.
(Em termos de teste, deve haver cobertura e um teste simples seria suficiente para validá-la, só precisamos confirmar que não há regressão)