Postgresql: недостаточно общей памяти из-за максимального количества блокировок на транзакцию с использованием временной таблицы - PullRequest
0 голосов
/ 07 января 2020

Я использую Postgresql 9.6. У меня есть сохраненный pro c, который вызывается Scala. Этот сохраненный pro c является оберткой, то есть он будет вызывать другие сохраненные procs для каждого входного списка, переданного в обертке. Например, оболочка имеет входной список из 100 элементов, поэтому внутренний хранимый pro c будет вызываться 100 раз для каждого элемента. Внутренний pro c - это тяжеловесный pro c, который создает 4-5 временных таблиц, обрабатывает данные и возвращает данные. Таким образом, оболочка соберет все данные и, наконец, завершит.

get_data_synced(date, text, integer[])

Здесь текст разделен запятыми (10-1000 в зависимости от регистра использования).

В основном проблема заключается в том, что если я передам большее число 100-200 пунктов, т.е. в al oop мы много раз вызываем внутренние процессы, это выдает ошибку:

SQL execution failed (Reason: ERROR: out of shared memory
Hint: You might need to increase max_locks_per_transaction.

I понимать, что создание временной таблицы внутри внутренней функции создаст блокировки. Но каждый раз, когда вызывается pro c, сначала нужно DROP, а затем СОЗДАТЬ временную таблицу.

DROP TABLE IF EXISTS _temp_data_1;
CREATE TEMP TABLE _temp_data_1 AS (...);

DROP TABLE IF EXISTS _temp_data_2;
CREATE TEMP TABLE _temp_data_2 AS (...);

..
..
..

Так что, даже если pro c вызывается 1000 раз, первое, что он делает, это удалить таблицу (которая должна освободить блокировки?), а затем создать таблицу.

Для max_locks_per_transaction задано значение 256.

Теперь транзакция не заканчивается, пока моя функция-обертка (внешняя функция) не завершится. более, верно? Таким образом, это означает, что даже если я удаляю временную таблицу, блокировки не снимаются?

Есть ли способ снять блокировку временной таблицы сразу после завершения моей функции?

1 Ответ

0 голосов
/ 08 января 2020

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

Для обходных путей, почему бы просто не обрезать таблицу, а не удалить ее и заново создать, если она уже существует?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...