Отладка Postgres ‘слишком много уведомлений в очереди УВЕДОМЛЕНИЙ’

#postgresql #notifications #queue #pg-promise #pg-notify

#postgresql #уведомления #очередь #pg-обещание #pg-уведомление

Вопрос:

Я использую таблицу Postgres, которая получает 2000-3000 обновлений в секунду. Я использую для обновления запросов к этой таблице, сгенерированных с помощью помощника по обновлению библиотеки pg-promise.

Каждое обновление запускает уведомление с помощью функции pg_notify(). Некоторые скрипты nodejs обрабатывают эти уведомления. По какой-то причине в журналах Postgres продолжают появляться сообщения «слишком много уведомлений в очереди УВЕДОМЛЕНИЙ», а также указание на размер очереди уведомлений, который продолжает увеличиваться до 100%. Я прочитал несколько сообщений, таких как: https://postgrespro.com/list/thread-id/1557124 или https://github.com/hasura/graphql-engine/issues/6263 но я не могу найти способ отладить эту проблему. Какой был бы хороший способ подойти к этой ситуации?

Комментарии:

1. PostgreSQL документирует это — см. Примечания .

2. Да, я прочитал это, но мне не очень понятно, что означает » еще не обработано всеми сеансами прослушивания — «. Я использую событие «уведомление» реализации pg-узла, насколько я понимаю, каждый раз, когда это событие запускается, уведомление обрабатывается.

3. Ваша проблема связана не с библиотекой или даже средой NodeJS, а строго с сервером, и поэтому вам нужно подойти к этому соответствующим образом — либо изменив стратегию уведомлений, либо стратегию обновления / тома, либо даже отслеживая размер очереди с помощью функции в документации.

Ответ №1:

Похоже, что ваш слушатель недостаточно быстро обрабатывает уведомления или, возможно, вообще не использует их. Итак, первым шагом будет что-то вроде регистрации обработки каждого уведомления из кода вашего приложения, чтобы выяснить, что происходит на самом деле.

Комментарии:

1. что вы подразумеваете под потреблением? Я использую событие уведомления библиотеки pg-node, поэтому каждый раз, когда запускается уведомление, оно запускает обратный вызов, где я что-то делаю.

2. pg_notify вызывается в триггере таблицы при обновлении. Вы предполагаете, что я должен где-то регистрировать каждый вызов pg_notify и сравнивать этот журнал с журналом, созданным обратными вызовами событий уведомлений. OK. Будет ли это сделано? И что делать, если некоторые уведомления отсутствуют?

3. «таким образом, каждый раз, когда запускается уведомление, оно запускает обратный вызов, где я делаю что-то» Да, это то, что вы хотите, чтобы произошло. Это работает? Откуда вы знаете?

4. Большинство из них работают. Я не мог знать наверняка, потому что все выглядит так, как ожидалось. Единственная неприятность — это неконтролируемое увеличение размера очереди. Вы говорите, что некоторые события уведомлений не запускаются? В чем может быть причина? Я проверю это, зарегистрировав как уведомления, так и события срабатывания уведомлений.

Ответ №2:

Это может быть связано с длительной транзакцией, которая блокирует выпуск старых сообщений из буфера. Процесс описан в руководствах и несколько аналогичен очистке — старые транзакции должны завершиться, чтобы очистить старые данные.

Проблема в том, что любой длительный запрос может задержать очистку; для меня это был процесс, который выполнял прослушивание — он был разработан, чтобы просто продолжать работать вечно. В журнале сервера PG есть внутренний PID, который может быть виновником, поэтому вы можете посмотреть его в pg_stat_activity и продолжить оттуда.