Alors que je travaillais sur un conteneur local où j’ai importé des données d’un forum SMF2 avec plus de 20 ans d’activité, je suis tombé sur un bug bloquant avec Topic.reset_all_highest.
Après l’importation des données, ma base de données affiche environ 60 000 sujets réguliers et environ 400 000 sujets de messages privés, et les requêtes dans Topic.reset_all_highest provoquent une sorte de croissance géométrique des lignes, ce qui fait que mon disque manque d’espace (avec 120 Go libres au départ).
J’essaie actuellement de diviser les requêtes en blocs gérables et de les exécuter directement dans Postgres, mais c’est bien sûr sous-optimal (et je ne suis pas sûr que cela fonctionne et que cela donne les bons résultats).
J’ai essayé de voir si quelqu’un d’autre avait eu ce genre de problème, mais je n’ai rien trouvé, alors je me demande si cela pourrait être lié à ma propre configuration - j’utilise la dernière version Docker, pour information.
J’ai récemment effectué une importation de taille modeste qui semble également bloquée indéfiniment sur Topic.reset_all_highest et j’ai dû tuer la requête dans Postgres pour continuer. Je n’avais pas eu ce problème auparavant et je pensais que c’était peut-être simplement que mon serveur postgres était surchargé (il a un tas de sites connectés).
Ma prochaine étape a été de passer à un autre serveur postgres, mais je ne m’y suis pas encore attelé.
Après que les deux premières parties de mon expérience de « requête divisée » se soient déroulées sans problème (X et Y pour les sujets publics), j’ai essayé avec celle de Z, et elle s’est bloquée - c’est-à-dire que la requête était active selon l’activité de postgres, et top montrait le processus en cours d’exécution à 100 %.
J’ai donc re-examiné le SQL et j’ai trouvé le problème : les deux requêtes se terminent comme ceci
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
)
(l’autre a ‘private_message’ comme archétype, bien sûr)
Ce qui signifie que la requête manque
Z.topic_id = topics.id - ce qui provoque l’augmentation géométrique.
Changer la clause WHERE des requêtes en
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
)
a résolu le problème pour moi.
Dois-je ouvrir une PR ?
Je le penserais. Si vous pouviez trouver un commit qui a cassé cela, ce serait encore plus convaincant.
J’ai ouvert une PR pour cela, avec quelques limitations malheureuses (c’est-à-dire que je ne peux pas imaginer comment tester ce changement).
Ce changement semble correct, je le fusionne.
(En termes de tests, il devrait y avoir une couverture et un test simple suffirait pour le valider, il faut juste confirmer qu’il n’y a pas de régression)