Jobs::SyncTopicUserBookmarked в цикле использует 100% CPU

За последние ~18 часов наш сервер использует почти 100% процессорного времени.

При проверке Sidekiq видно, что он занят выполнением одних и тех же 5 задач:

Время выполнения всегда указано как «Только что», и задачи, похоже, постоянно перезапускаются для одних и тех же трёх идентификаторов тем.

Я пытался перезапустить Discourse, но ситуация не изменилась.

Не уверен, связано ли это, но проблема началась примерно через 24 часа после обновления с версии 3.3.3 до 3.3.4. Я не вижу никаких недавних изменений в app/jobs/regular/sync_topic_user_bookmarked.rb и не нашёл в версии 3.3.4 изменений, которые могли бы быть связаны с этим, но я не знаком с кодовой базой.

Есть ли какие-то идеи, что может происходить?

Обновление по этому вопросу. Мы только что заметили, что три идентификатора тем, по которым задачи продолжают перезапускаться, относятся к темам, для которых мы вчера активировали автоматическое удаление ответов — примерно в то же время, когда всё началось. Все они очень большие темы.

Итак, мы знаем триггер, но SQL-запрос, который повторяется, похоже, не использует пакетную обработку, поэтому я не понимаю, почему он выполняется снова и снова.

Это запускается какой-то другой задачей, которая всё ещё удаляет большое количество ответов, и Jobs::SyncTopicUserBookmarked выполняется для каждого удалённого поста? Или это баг?

Мы отключили автоматическое удаление в одной из больших тем, и это, похоже, не повлияло на повторяющиеся вызовы Jobs::SyncTopicUserBookmarked для этого идентификатора темы.

Я уменьшил SIDEKIQ_WORKERS до 2, и вскоре очередь (с множеством ожидающих задач) очистилась, и больше нет выполняющихся Jobs::SyncTopicUserBookmarked:thinking:

Перед этим я заметил, что нижеприведённый запрос выполнялся несколько раз одновременно (с использованием одного и того же ID темы):

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;

Мне не совсем понятно, как PostgreSQL выполняет несколько операторов в одном запросе, но если этот запрос выполняется несколько раз одновременно, не может ли это привести к циклу?