Подтвердить что ты не робот

Как освободить возможные блокировки строк Postgres?

Я запустил инструкцию update в большой таблице PostgreSQL через интерфейс phpPgAdmin. Это затянулось, так как оно длилось слишком долго.

Теперь я могу обновить некоторые строки из этой таблицы, но не все. Попытка обновления некоторых строк будет зависать.

Блокированы ли строки? Как я могу разрешить обновление этих строк?

4b9b3361

Ответ 1

Какую версию PostgreSQL вы используете? Следующее предполагает 8.1.8 или новее (это может относиться и к более ранним версиям, я не знаю).

Я предполагаю, что вы имеете в виду, что время истечения срока действия phpPgAdmin - бэкэнд PostgreSQL займет столько времени, сколько потребуется для завершения запроса/обновления. В этом случае возможно, что исходный сеанс все еще жив, и запрос UPDATE все еще запущен. Я предлагаю запустить следующий запрос (взятый из глава 24 документов PostgreSQL) на компьютере, на котором размещен серверный процесс PostgreSQL, чтобы узнать, является ли сеанс все еще жив:

ps auxwww|grep ^postgres

Должно появиться несколько строк: 1 для мастер-процесса postmaster и 1 для процессов "писатель", "статистика статистики" и "сбор статистики". Любые оставшиеся строки предназначены для процессов, обслуживающих соединения БД. Эти строки будут содержать имя пользователя и имя базы данных.

Надеюсь, из этого вы увидите, что сеанс, который вы выполнили, с оригинальным UPDATE, по-прежнему висит вокруг. Хотя в теории вы можете найти более подробную информацию SELECT ing из системного представления pg_stat_activity, по умолчанию PostgreSQL не настроен для заполнения наиболее полезных полей (например, current_query и query_start). См. Главу 24, как включить это в будущем.

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

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

Ответ 2

Можно увидеть блокировки.

Вот представление, чтобы сделать его немного проще, чем напрямую использовать pg_locks:

CREATE OR REPLACE VIEW public.active_locks AS 
 SELECT t.schemaname,
    t.relname,
    l.locktype,
    l.page,
    l.virtualtransaction,
    l.pid,
    l.mode,
    l.granted
   FROM pg_locks l
   JOIN pg_stat_all_tables t ON l.relation = t.relid
  WHERE t.schemaname <> 'pg_toast'::name AND t.schemaname <> 'pg_catalog'::name
  ORDER BY t.schemaname, t.relname;

Затем вы просто выбираете из представления:

SELECT * FROM active_locks;

И убей его:

SELECT pg_cancel_backend('%pid%');

Другие решения: http://wiki.postgresql.org/wiki/Lock_Monitoring

Ответ 3

Я никогда не работал с PostreSql, но если он похож на других, я бы сказал, что вам нужно убить соединение/завершить транзакцию, в которой хранятся блокировки.