Поиск и снятие блокировок с таблиц PostgreSQL

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

Обнаружение блокировки

Первое, что может дать вам подсказку о наличии блокировки на таблице, это то, что вы не можете сделать простые вещи, которые вы обычно можете сделать, например, удалить строку из таблицы:

Перечисление блокировок

Postgres содержит тонну отличной статистической информации в таблицах с метаданными о том, как работает сама система Postgres. Одной из таких таблиц является pg_locks, где мы можем объединить ее с pg_class, чтобы иметь возможность искать по имени таблицы. Так, с именем таблицы search_hit я могу сделать запрос:

И получите:

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

Сопоставление запросов с блокировками

Я даже могу увидеть запросы, которые вызвали эти блокировки, если посмотрю на таблицу pg_stat_activity, фильтруя по этим pids:

И получите что-то вроде этого:

Когда у меня есть запрос, я могу вернуться к своему коду, найти запрос и навсегда решить проблему.

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

Но в этот момент может возникнуть процесс, который просто нужно убить.

Удаление блокировок

Есть несколько способов уничтожить процессы, вызывающие блокировки. Если вы выполняете запрос в интерактивном режиме, просто остановите его с помощью отмены запроса пользователем (например, используя ctrl-c из psql cli).

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

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

Это был вежливый способ спросить (т.е. pg_cancel_backend). Более силовым методом является:

Проверка снятых блокировок

После отмены или прекращения действия существовавших блокировок вы должны иметь возможность запросить pg_locks, соединить с pg_class и создать фильтр для pids в pg_stat_activity, как показано выше, чтобы еще раз убедиться, что блокировки сняты.

А теперь та простая вещь, которую я хотел сделать:

будет действительно работать. Ваши блокировки навсегда останутся в страхе перед вашей силой.

Понравилась статья? Поделиться с друзьями:
Добавить комментарий