#postgresql #locks
Вопрос:
Я в тупике по поводу возникшей у меня проблемы. Истинный контекст довольно сложен, но я могу свести его к этим функциональным моментам (все остальное не связано с проблемной таблицей).:
- У меня есть функция запуска, которая содержит несколько
SELECT
s, а затемUPDATE
- Выполнение обновления занимает неоправданно много времени («неоправданно» = > 1,4 с)
- Те же самые точные запросы, выполняемые вне триггера (для одних и тех же строк, параметров и т.д.), Не имеют никаких проблем (т. Е. Они выполняются менее чем за 1-2 мс).
- Я почти уверен, что индексы и т. Д. Работают по мере необходимости, т. Е. Не должно быть никаких проблем.
- Нет никаких циклических триггеров
- В таблице назначения есть триггер on, но даже при его удалении поведение остается прежним.
- Я провел много тестов безрезультатно, но они довольно значимы:
- когда обновление заменяется на a
SELECT
, время отклика, как и ожидалось, быстро - когда обновление заменяется на a
SELECT... FOR UPDATE
, время ответа замедляется, такое же, как и при обновлении - ^ это (а также другие вещи) привело меня, возможно, к мысли, что задержка тратится на ожидание достижения блокировки
- когда обновление заменяется на a
Никаких других транзакций на самом деле не происходит на этом столе. Я действительно в замешательстве.
Контекст сервера: Это выполняется в AWS/RDS на db.m5.xlarge.
Что я ищу, так это есть ли способ получить некоторую информацию о блокировках, которые происходят в середине транзакции, или, возможно, даже историю приобретенных блокировок? Или что-нибудь еще, что может дать мне представление о том, что вызывает задержку, которая, кажется, так тесно связана с получением блокировки на этом столе.
К сожалению, просто чтобы сделать все еще более разочаровывающим, я не могу воспроизвести проблему, когда я пытаюсь использовать EXPLAIN
в теле функции. Единственный способ сделать это (насколько мне известно) — использовать EXECUTE...
синтаксис со строкой запроса. У этого нет задержки — это также бесполезно для триггера.
Комментарии:
1. Вы можете установить log_lock_waits, тогда он будет регистрировать любые ожидания блокировки дольше, чем deadlock_timeout (по умолчанию: одна секунда). Если это ничего не показывает, вы можете регистрировать планы ОБЪЯСНЕНИЯ с помощью auto_explain, в частности, используя log_analyze, log_nested_statemets и log_min_duration.
2. @jjanes Это должно быть ответом.
3. @jjanes Спасибо, это именно то, о чем я думал / искал и не мог вспомнить.