PostgreSQL Error 25006 read_only_sql_transaction: Причины и Решение
- Ошибка приложения:
ERROR: 25006: cannot execute INSERT in a read-only transaction(или UPDATE/DELETE/CREATE). - Сбой записи данных при случайном подключении пользователей или регламентных заданий 1С к реплике (Read-Only Standby / Hot Standby).
- Блокировка модификации данных после аварийного переключения (failover) кластера Patroni / Pacemaker.
- Отказ выполнения DDL-операций временных таблиц в базах данных для отчетов.
1. Проверка текущего статуса узла (Primary vs Standby)
Выполните запрос к серверу, чтобы определить, является ли узел репликой, доступной только для чтения:
SELECT pg_is_in_recovery();Если запрос возвращает true, данный инстанс является Standby-репликой и не принимает операции записи.
2. Проверка параметров read_only на уровне сессии и сервера
SHOW default_transaction_read_only;
SHOW transaction_read_only;Если параметр включен на основном мастере (Primary), отключите его глобально:
ALTER SYSTEM SET default_transaction_read_only = 'off';
SELECT pg_reload_conf();3. Проверка прав и настроек роли (пользователя)
Параметр default_transaction_read_only мог быть назначен конкретной учетной записи или базе данных:
-- Проверка настроек пользователя базы
SELECT rolname, rolconfig FROM pg_roles WHERE rolname = 'v8_user';
-- Сброс принудительного read-only режима для пользователя
ALTER ROLE v8_user RESET default_transaction_read_only;
-- Сброс принудительного read-only режима для базы данных
ALTER DATABASE enterprise_db RESET default_transaction_read_only;
4. Корректировка маршрутизации в HA-Proxy / PgBouncer
Если используется балансировщик нагрузок (HAProxy / Keepalived / Patroni REST API), убедитесь, что порт записи направляет трафик исключительно на узел со статусом Primary:
# Пример секции HAProxy для проверки Primary узла
backend pg_cluster_primary
mode tcp
option httpchk GET /primary
http-check expect status 200
default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
server srv-pg-01 192.168.1.11:5432 maxconn 200 check port 8008
server srv-pg-02 192.168.1.12:5432 maxconn 200 check port 8008
Частые вопросы (FAQ)
Почему ошибка 25006 возникает после планового переключения серверов в Patroni?
При переключении старый мастер становится Standby. Если клиентское приложение (или кластер 1С) не сбросило пул подключений и продолжает посылать запросы на старый IP-адрес/узел, они попадают на реплику в режиме read-only.
Можно ли создавать временные таблицы (TEMPORARY TABLE) на Standby-сервере?
Нет. В PostgreSQL на физических репликах (Hot Standby) любые операции, генерирующие транзакционные логи (WAL) или меняющие системные каталоги, включая создание временных таблиц, строго запрещены.
Как перевести упавшую реплику в режим мастера вручную?
Для ручного промоута выполните команду в консоли ОС: pg_ctl promote -D /var/lib/postgresql/data или через SQL: SELECT pg_promote();.
Может ли транзакция стать read-only из-за нехватки места на диске?
Некоторые облачные провайдеры и управляемые СУБД автоматически переводят PostgreSQL в режим default_transaction_read_only = on при падении свободного места на диске ниже критического порога (например, менее 5%).