Au cours des ~18 dernières heures, notre serveur utilise près de 100 % du CPU.
En regardant Sidekiq, il est occupé à exécuter les mêmes 5 tâches :
Elles sont toujours indiquées comme “Il y a un instant” et semblent toujours se relancer sur les mêmes 3 identifiants de sujet.
J’ai essayé de redémarrer Discourse, mais la situation n’a pas changé.
Je ne sais pas si c’est lié, mais cela a commencé ~24 heures après la mise à jour de la version 3.3.3 à la version 3.3.4. Je ne vois aucun changement récent dans app/jobs/regular/sync_topic_user_bookmarked.rb et je n’ai pas pu repérer de changement dans la version 3.3.4 qui pourrait être lié, mais je ne connais pas le code source.
Une idée de ce qui pourrait se passer ?
Une mise à jour à ce sujet. Nous venons de remarquer que les 3 identifiants de sujets sur lesquels les tâches continuent de s’exécuter sont des sujets pour lesquels nous avons activé la suppression automatique des réponses hier, peu avant que cela ne commence. Ce sont tous de très grands sujets.
Nous connaissons donc le déclencheur, mais le SQL répété ne semble pas effectuer de traitement par lots, je ne vois donc pas pourquoi il est réexécuté encore et encore.
Est-ce que cela est déclenché par un autre travail qui supprime toujours un grand nombre de réponses et que Jobs::SyncTopicUserBookmarked est exécuté pour chaque message supprimé ? Ou s’agit-il d’un bug ?
Nous avons supprimé la suppression automatique de l’un des grands sujets et cela n’a pas semblé avoir d’effet sur les appels répétés de Jobs::SyncTopicUserBookmarked sur cet identifiant de sujet.
J’ai réduit SIDEKIQ_WORKERS à 2 et, peu de temps après, la file d’attente (avec beaucoup de choses en attente) s’est vidée et il n’y a plus de Jobs::SyncTopicUserBookmarked en cours d’exécution… 
Avant d’essayer cela, j’ai vu la requête ci-dessous s’exécuter plusieurs fois simultanément (en utilisant le même identifiant de sujet) :
SELECT bookmarks.user_id, COUNT(*)
INTO TEMP TABLE tmp_sync_topic_user_bookmarks
FROM bookmarks
LEFT JOIN posts ON posts.id = bookmarks.bookmarkable_id AND bookmarks.bookmarkable_type = 'Post'
LEFT JOIN topics ON (topics.id = bookmarks.bookmarkable_id AND bookmarks.bookmarkable_type = 'Topic') OR
(topics.id = posts.topic_id)
WHERE (topics.id = 51303 OR posts.topic_id = 51303)
AND posts.deleted_at IS NULL AND topics.deleted_at IS NULL
GROUP BY bookmarks.user_id;
UPDATE topic_users
SET bookmarked = true
FROM tmp_sync_topic_user_bookmarks
WHERE topic_users.user_id = tmp_sync_topic_user_bookmarks.user_id AND
topic_users.topic_id = 51303 AND
tmp_sync_topic_user_bookmarks.count > 0;
UPDATE topic_users
SET bookmarked = false
FROM tmp_sync_topic_user_bookmarks
WHERE topic_users.topic_id = 51303 AND
topic_users.bookmarked = true AND
topic_users.user_id NOT IN (
SELECT tmp_sync_topic_user_bookmarks.user_id
FROM tmp_sync_topic_user_bookmarks
);
DROP TABLE tmp_sync_topic_user_bookmarks;
Je ne comprends pas bien comment PostgreSQL exécute plusieurs instructions dans une seule requête, mais si elle est exécutée plusieurs fois simultanément, cela pourrait-il causer une boucle d’une manière ou d’une autre ?