SQLite LinuxWindowsmacOS

SQLite: attempt to write a readonly database

  • Обновлено
  • Чтение ≈ 4 минуты

Краткий ответ

Файл или каталог базы недоступны для записи пользователю веб-сервера. Выдайте права на файл и каталог (нужны для журнала).

В этой статье
  1. Что означает ошибка
  2. Причины и решения
  3. Пошаговое решение
  4. Права
  5. Файловая система и защита
  6. Откройте базу корректно

#Что означает ошибка

Сообщение
readonly database

«attempt to write a readonly database» значит, что процесс не может записывать в файл базы или в её каталог. SQLite создаёт временные файлы (-journal, -wal, -shm) рядом с базой, поэтому права на каталог так же важны, как права на файл.

Чаще всего причина — владелец файла не совпадает с пользователем веб-сервера.

Иногда файловая система смонтирована только для чтения.

Файл или каталог базы недоступны для записи пользователю веб-сервера. Выдайте права на файл и каталог (нужны для журнала).

#Причины и решения

Возможная причинаКак узнатьЧто делать
Нет прав на файлchmod.Пользователь службы не имеет права писать в файл либо каталогПроверьте владельца конкретного процесса и настройте минимальные права.
Нет прав на каталогЖурнал.Файловая система смонтирована ro либо закончился диск/inodeИзучите findmnt, df и журналы ядра; не перемонтируйте вслепую.
Файловая система read-onlyМонтирование.Docker том смонтирован как read-only или UID не совпадаетПроверьте mounts и пользователя контейнера.
SELinuxКонтекст.SELinux/AppArmor запретил доступ к файламИзучите подтверждённые сообщения аудита, не отключайте защиту.

#Пошаговое решение

  1. Проверьте владельца файла и каталогаЭто проверка для владельца сервера или разработчика, имеющего доступ к файлу SQLite; обычному посетителю сайта менять права нельзя. Сначала выясните абсолютный путь к базе в настройках приложения и имя системного пользователя, под которым запускается веб-сервер/служба (например, по настройке systemd User= или процессу PHP-FPM). На Linux в терминале выполните ls -ld /путь/к/каталогу и ls -l /путь/к/каталогу/app.db, подставив реальные пути. Проверьте права на сам файл, каталог и родительские каталоги: процессу могут быть нужны права создания соседних файлов -wal/-shm или журнала. Ничего пока не меняйте.
  2. Выдайте права пользователю процессаЕсли по результатам шага 1 права недостаточны, сделайте резервную копию штатным .backup, согласуйте пользователя процесса и исправьте доступ точечно, а не на всём сайте. Например, администратор Linux может задать владельца конкретной базы sudo chown appuser:appgroup /srv/app/data/app.db и каталога /srv/app/data, но appuser, appgroup и пути здесь заглушки; используйте действительные значения. Не применяйте chmod -R 777 или смену владельца корня сайта: это создаёт уязвимости. После исправления проверьте запись через функциональность приложения, не выполняя непроверенных SQL над рабочими данными.
  3. Проверьте, не только ли чтение файловая системаЕсли разрешения правильные, проверьте состояние файловой системы: findmnt -T /полный/путь/к/app.db покажет точку монтирования и параметры, df -h и df -i — свободное место и inode, dmesg/journalctl -k — сообщения ядра (иногда нужны права администратора). Если раздел перешёл в ro, есть ошибки носителя или закончилось место, остановите записи и разберитесь с инфраструктурой. Не перемонтируйте том в rw «на всякий случай» и не запускайте fsck по смонтированному рабочему разделу.
  4. Проверьте SELinux и Docker-томаВ Docker проверьте docker inspect ИМЯ_КОНТЕЙНЕРА (подставьте его) и настройки volumes: в compose-файле: каталог или файл SQLite не должен быть смонтирован как :ro, если нужны записи. Сверьте пользователя внутри контейнера и права тома на хосте. В системе с SELinux/ AppArmor изучите журналы запретов у администратора — без подтверждённой причины не отключайте защиту и не запускайте массовый chcon. На Windows дополнительно проверьте атрибут «Только чтение», права учётной записи службы и расположение базы.
  5. Перезапустите сервисКогда выявленная причина устранена, запустите приложение штатным способом и повторите действие, которое должно записать данные; затем прочитайте только что созданную запись и проверьте логи. Перезапуск службы нужен лишь тогда, когда изменена конфигурация или работающий процесс не подхватил права/том; предварительно предупредите пользователей. Если сохраняется readonly, получите расширенный код ошибки SQLite (например, SQLITE_READONLY_DIRECTORY) и уточните точный путь открываемой базы, чтобы не чинить другую копию.

#Права

Прежде чем менять доступ, установите реальный абсолютный путь БД, пользователя процесса и режим журналирования, затем выполните ls -l для файла и ls -ld для каталога. Нельзя автоматически назначать владельца www-data или права 775: PHP-FPM может работать от другого пользователя, а дополнительные права создадут угрозу. Используйте штатную резервную копию и точечную настройку доступа.

#Файловая система и защита

Проверьте findmnt -T для точного файла, df -h/df -i, журнал ядра и параметры тома Docker. Для SELinux сначала изучите записи аудита; не выполняйте произвольный chcon и не отключайте защиту. На Windows проверьте ACL учётной записи конкретной службы, а не только флаг «Только чтение».

#Откройте базу корректно

Если приложение открывает SQLite в URI-режиме mode=ro, запись не предусмотрена и необходимо выяснить, почему выбран этот режим. Блокировка другими процессами чаще порождает database is locked, а не readonly. Не убивайте держателей файла без диагностики. После согласованного исправления пути или прав перезапускать сервис нужно только при необходимости.

Linux · Терминал (Bash)Команда
Только чтение прав, файловой системы и свободного места. Не копируйте пример пути без замены.
# Диагностика на Linux: подставьте существующий абсолютный путь
ls -ld /srv/app/data
ls -l /srv/app/data/app.db
findmnt -T /srv/app/data/app.db
df -h /srv/app/data

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 1 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.