PostgreSQL Error 55006 object_in_use: Завершение сессий и Решение
- Ошибка DDL:
ERROR: 55006: database "enterprise_db" is being accessed by other users. - Ошибка при попытке переименовать или удалить таблицу/базу данных в PostgreSQL.
- Сбой выполнения регламентного скрипта восстановления базы 1С из бэкапа (
DROP DATABASE). - Невозможность сбросить схему данных или табличное пространство (Tablespace).
1. Поиск активных сессий, удерживающих объект
Найдите все подключения к целевой базе данных:
SELECT pid, usename, client_addr, application_name, state, query_start, query
FROM pg_stat_activity
WHERE datname = 'enterprise_db' AND pid <> pg_backend_pid();
2. Принудительное завершение блокирующих соединений
В PostgreSQL 13+ доступно безопасное удаление базы с авто-отключением клиентов:
-- PostgreSQL 13 и новее:
DROP DATABASE enterprise_db WITH (FORCE);
Для более ранних версий PostgreSQL принудительно разорвите сессии вручную:
-- 1. Запретить новые подключения к базе:
ALTER DATABASE enterprise_db WITH ALLOW_CONNECTIONS false;
-- 2. Завершить все активные процессы:
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'enterprise_db' AND pid <> pg_backend_pid();
-- 3. Выполнить операцию удаления/переименования:
DROP DATABASE enterprise_db;
3. Освобождение заблокированных табличных пространств (Tablespaces)
Если DROP TABLESPACE падает с кодом 55006: tablespace "..." is not empty, найдите оставшиеся в нем объекты:
SELECT c.relname, c.relkind, d.datname
FROM pg_class c
JOIN pg_tablespace t ON c.reltablespace = t.oid
LEFT JOIN pg_database d ON c.relowner = d.datdba
WHERE t.spcname = 'my_fast_storage';
4. Отключение пулеров PgBouncer / Cluster 1С
Перед проведением DDL административных работ временно переведите PgBouncer в режим паузы:
# В консоли pgbouncer (порт 6432):
PAUSE enterprise_db;
KILL enterprise_db;
Частые вопросы (FAQ)
Чем отличается pg_cancel_backend от pg_terminate_backend?
pg_cancel_backend(pid) лишь мягко отменяет текущий выполняемый SQL-запрос, сохраняя сетевое соединение клиента. pg_terminate_backend(pid) немедленно жестко закрывает сессию и разрывает TCP-сокет.
Почему после pg_terminate_backend соединения мгновенно появляются снова?
Кластер серверов 1С:Предприятие или пул соединений (PgBouncer) настроены на авто-реконнект: при разрыве они немедленно открывают новые сессии. Сначала установите ALLOW_CONNECTIONS = false.
Можно ли переименовать базу данных, если в ней кто-то работает?
Нет, команда ALTER DATABASE ... RENAME TO требует эксклюзивной блокировки всей базы и завершится ошибкой 55006 при наличии хотя бы одной активной сессии.
Как закрыть сессию самого себя, вызывающую 55006?
Условие pid <> pg_backend_pid() гарантирует, что вы не завершите собственную сессию в psql, через которую администрируете сервер.