Длительная функция блокировки базы данных?

Является ли нормальным, что функция получает блокировку на уровне базы данных, которая предотвращает автоматическую очистку и создание индекса для совершенно несвязанных таблиц?

У меня есть долго работающая хранимая процедура, которая читает из одной таблицы и записывает _1 _ / _ 2_ данные в другую таблицу. Во время выполнения скрипта (что может занять почти час в больших системах) вся автоматическая очистка останавливается и пытается выполнить такие действия, как создание индексов (CREATE UNIQUE INDEX CONCURRENTLY) для несвязанных таблиц. чтобы заблокировать. Как только хранимая процедура завершается, заблокированные процессы завершаются.

Думая, что что-то внутри хранимой процедуры неправильно блокирует какой-то ресурс, я переписал это буквально как сон:

CREATE OR REPLACE FUNCTION summarize_day(p_agg_date date)
RETURNS int AS
$$
BEGIN
  SELECT pg_sleep(120);
  RETURN NULL;
END;
$$ LANGUAGE plpgsql;

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

Есть ли способ закодировать его, чтобы НЕ блокировать базу данных для других операций во время выполнения этой длительной процедуры?


person KenHuffman    schedule 31.10.2018    source источник


Ответы (2)


VACUUM не может помечать мертвые кортежи длительными транзакциями. Система отслеживает самый старый идентификатор транзакции (xid), который все еще может быть видим в любом снимке (даже без задействованных конкурирующих блокировок). Кортежи с более поздним xid не могут быть удаляется до завершения блокирующих транзакций. В этом отношении длительные транзакции могут VACUUM остановиться.

Связанный:

Однако я не могу придумать, каким образом CREATE UNIQUE INDEX в несвязанной таблице должен быть напрямую затронут. Могут быть другие транзакции, остановленные блокировками длительной транзакции, которые, в свою очередь, удерживают блокировки CREATE UNIQUE INDEX. Таким образом, могут увеличиваться блокировки длительных транзакций. Так что делайте ваши транзакции краткими при одновременной нагрузке записи.

Связанный:

Дальнейшее чтение:

«Когда автоочистка не пылесосит» (сообщение в блоге Томаса Вондры )

person Erwin Brandstetter    schedule 31.10.2018

Человек, отвечавший на вопрос, немного отредактировал мой исходный вопрос и ответил на очень общий вопрос, а не на конкретный, который я задавал.

Первоначальный вопрос заключался в том, может ли хранимая процедура PostgreSQL поддерживать небольшие транзакции вместо одной длительной. Начиная с версии 11, он может:

Управление транзакциями

person KenHuffman    schedule 27.11.2018
comment
Вы должны были упомянуть, что вы используете Postgres 11, и вы должны были включить пример хранимой процедуры, а не функции, если это контекст вашего вопроса (я уверен, что Эрвин тогда не заменил бы процедуру функцией) - person a_horse_with_no_name; 27.11.2018
comment
В исходном вопросе я упомянул postgresql и что это хранимая процедура. Этот текст был отредактирован. (Я не упомянул версию 11 специально, потому что в то время я не знал, что эта версия предлагает исправление, которое я искал.) В будущем я обязательно буду задавать только те вопросы, на которые уже знаю ответ. - person KenHuffman; 28.11.2018