Ошибка «database is locked» (SQLITE_BUSY) в n8n: Причины и окончательное решение
Если при запуске нескольких сценариев или получении частых вебхуков от Telegram и CRM ваш n8n начинает тормозить, выдавая ошибку Error: SQLITE_BUSY: database is locked, это значит, что встроенная база данных SQLite исчерпала свои архитектурные возможности.
💡 Почему это происходит: SQLite - это файловая база данных, которая блокирует весь файл на запись при любой транзакции. Когда два сценария n8n одновременно пытаются записать лог или обновить статус выполнения, второй запрос получает отказ в доступе.
Как выглядят ошибки в логах сервера (поисковые маркеры)
При сбоях SQLite в выводе команды docker logs n8n обычно появляются следующие ошибки:
NodeApiError: SQLITE_BUSY: database is locked
Error: SQLITE_BUSY: database is locked, executing 'COMMIT;'
SqliteError: database disk image is malformed
Почему SQLite не подходит для Production-задач
Стандартный образ n8n по умолчанию использует SQLite ради простоты первого запуска. Однако при реальной нагрузке возникают критические проблемы:
- Потеря входящих вебхуков: Если база заблокирована, HTTP-запросы от внешних сервисов завершаются таймаутом.
- Зависание интерфейса: Редактор сценариев перестаёт сохранять изменения и загружать историю выполнений.
- Коррупция файла БД: При резком перезапуске сервера файл
database.sqliteможет быть повреждён без возможности восстановления.
Подводные камни при миграции с SQLite на PostgreSQL
При самостоятельной замене базы данных часто возникают типичные ошибки администраторов:
- Потеря истории выполнений и учётных записей: Если просто переключить переменные окружения на PostgreSQL на рабочем сервере, n8n запустится с чистой пустой базой. Перенос существующих сценариев и credentials требует предварительного экспорта через CLI-команды
n8n export:workflow --allиn8n export:credentials --allс последующим импортом в новую БД. - Несовместимость ключа шифрования: Если при переносе на новый контур не сохранить переменную
N8N_ENCRYPTION_KEYиз старого контейнера, все ранее сохранённые пароли, токены и API-ключи станут нечитаемыми. - Отсутствие проверки готовности (Healthcheck): Контейнер n8n может попытаться подключиться к PostgreSQL до того, как база завершит инициализацию, что приведёт к циклу падений и перезагрузок (CrashLoopBackOff).
Архитектурное решение: Переход на PostgreSQL LTS
Официальная рекомендация разработчиков n8n для любых рабочих систем - использование полноценной реляционной СУБД PostgreSQL 16 LTS. PostgreSQL поддерживает тысячи параллельных транзакций с изоляцией строк, что полностью исключает блокировки.
Как выглядит правильная конфигурация в docker-compose.yml
Для работы n8n с PostgreSQL контейнеры связываются в единую внутреннюю сеть Docker:
version: '3.8'
services:
postgres:
image: postgres:16-alpine
restart: always
environment:
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=n8n_secure_pass
- POSTGRES_DB=n8n
volumes:
- pg_data:/var/lib/postgresql/data
n8n:
image: n8nio/n8n:latest
restart: always
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=n8n_secure_pass
depends_on:
- postgres
volumes:
pg_data:
Дополнительная оптимизация для высоких нагрузок
Даже на PostgreSQL рекомендуется настроить автоматическую очистку старых логов выполнения в environment контейнера n8n, чтобы база данных не разрасталась бесконечно:
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=14
- EXECUTIONS_DATA_PRUNE_MAX_COUNT=50000
Устали от зависаний и ошибки database locked?
Переведём ваш n8n с проблемного SQLite на отказоустойчивую базу PostgreSQL LTS, сохраним все ваши текущие сценарии и настроим автоочистку логов.
Заказать спасение и настройку