Блокировка таблиц в PostgreSQL

У меня есть функция PL/pgSQL, которая переносит данные из промежуточной таблицы в нашу целевую таблицу. Процесс выполняется каждую ночь. Иногда из-за перезагрузки сервера или некоторых проблем с обслуживанием мы запускаем процесс вручную.

Проблема, с которой я столкнулся: всякий раз, когда мы запускаем процесс вручную после 7 утра, он занимает почти 2 часа (чтение из промежуточной таблицы и вставка в целевую таблицу). Но всякий раз, когда он выполняется по расписанию, то есть до 7 утра, в среднем это занимает 22-25 минут.

В чем может быть проблема? Если необходимо, я могу поделиться своим фрагментом функции здесь.


person Yousuf Sultan    schedule 14.07.2015    source источник


Ответы (1)


Типичной причиной может быть общая параллельная активность в базе данных, которая конкурирует за те же ресурсы, что и ваша функция, и может вызвать конфликт блокировок. Проверьте свой журнал БД на наличие действий, начинающихся около 7 утра.

Вики Postgres о мониторинге блокировок

Функция всегда выполняется как одна транзакция. Блокировки приобретаются по пути и освобождаются только в конце транзакции. Это делает долго работающие функции особенно уязвимыми для конфликтов блокировок.

Вы можете оптимизировать общую производительность, а также поведение по отношению к одновременным транзакциям, чтобы ускорить их выполнение. Или более радикально: если это вообще возможно, разделите свою большую функцию на отдельные части, которые вы вызываете в отдельных транзакциях.

Как разделить огромные обновления:

Есть дополнительные вещи, которые следует учитывать при объединении нескольких больших операций в одну функцию:

person Erwin Brandstetter    schedule 15.07.2015
comment
Можете ли вы сказать, что означает состояние простоя запроса в Postgres? Я понял, что есть какое-то другое приложение, обращающееся к таблице, используемой вышеупомянутой функцией. Запросы других таблиц остаются в состоянии ожидания даже после их завершения? Как это повлияет на производительность? - person Yousuf Sultan; 15.07.2015
comment
@YousufSultan: состояние idle не обязательно подозрительно — это просто сеанс, ожидающий ввода. idle in transaction и idle in transaction (aborted) указывают на проблемы. См. stackoverflow.com/a/28596354/939860. - person Erwin Brandstetter; 15.07.2015
comment
Спасибо.... Проблема была решена путем закрытия сеансов других пакетных заданий, которые обращались к таблице. Они открывали там сессии, но они не закрывались. - person Yousuf Sultan; 16.07.2015
comment
@ЮсуфСултан. Пока они закрывают свою транзакцию, открытый сеанс вообще не должен быть проблемой. - person Erwin Brandstetter; 16.07.2015