SQLite SQLiteLinuxWindowsPHPPython

SQLite: После переноса файла SQLite приложение получает ошибку доступа

  • Обновлено
  • Чтение ≈ 3 минуты
  • Нужны права администратора

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

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

В этой статье
  1. Что происходит и когда инструкция применима
  2. Как отличить возможные причины
  3. Пошаговая диагностика и исправление
  4. Как проверить исправление
  5. Если исправление не помогло

#Что происходит и когда инструкция применима

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

Характерный признак: После переноса базы возникают unable to open database file, attempt to write a readonly database или ошибка создания журнала; до переноса приложение работало.

#Как отличить возможные причины

Возможная причинаКак узнатьЧто делать
Изменился владелецФайл был скопирован от root или от другой учётной записиstat показывает чужого владельцаСравнить с UID процесса
Нет доступа к каталогуSQLite при записи создаёт журнал и иногда -wal/-shmФайл читается, INSERT завершается ошибкойПроверить каталог и путь
Доступ запрещён политикойSELinux, AppArmor, ACL или привязка тома ограничивают процессРежим доступа файла выглядит правильнымНайти запрет в журнале ОС

#Пошаговая диагностика и исправление

  1. 1. Зафиксируйте точный путь и сообщение ошибкиВ журнале приложения найдите сообщение с полной строкой подключения. Уточните, был ли перенесён каталог целиком, изменён ли путь в .env/конфигурации и использует ли приложение абсолютный путь. Не создавайте новую пустую базу в попытке «исправить» отсутствие файла.
  1. 2. Убедитесь, что существующий файл действительно на новом местеНа Linux откройте терминал сервера и замените путь в примере на фактический. Файл должен существовать; «нет файла» означает проблему пути или незавершённый перенос, а не нехватку прав.
  2. Только чтение; не создаёт базу
    Linux · Терминал (Bash)Команда
    Только чтение; не создаёт базу. На Windows проверьте путь через Проводник и свойства файла.
    test -f /srv/app/data/app.db && stat -c '%U:%G %a %n' /srv/app/data/app.db || echo 'ФАЙЛ НЕ НАЙДЕН'
  1. 3. Проверьте доступ по всей цепочке каталоговВ Linux нужен проход (x) через каждый каталог до .db; при записи также необходима запись в каталог базы. Посмотрите права пути и сравните с пользователем PHP-FPM или systemd, определённым в настройках службы.
  2. Команда Linux; покажет права на все промежуточные каталоги
    Linux · Терминал (Bash)Команда
    Команда Linux; покажет права на все промежуточные каталоги. Если namei недоступен, используйте ls -ld по каждому каталогу.
    namei -l /srv/app/data/app.db
  1. 4. Выясните, кто реально открывает SQLiteЕсли проблема только на сайте, проверьте поле user в настройках нужного пула PHP-FPM или User= в файле службы systemd; владелец веб-корня не всегда совпадает с владельцем рабочего процесса. На управляемом хостинге запросите пользователя у администратора.
  1. 5. Проверьте чтение от имени нужного пользователя без изменения данныхАдминистратор Linux может выполнить запрос к существующей базе от имени пользователя процесса. При успешном открытии выводится имя таблицы или пустой список; отказ укажет на права или политику доступа.
  2. Дополнительная команда по теме
    Linux · Терминал (Bash)КомандаНужен sudo
    Только администратор сервера; www-data — ПРИМЕР, замените на реальную учётную запись процесса. Не используйте sudo от root вместо теста от рабочего пользователя.
    sudo -u www-data sqlite3 -readonly /srv/app/data/app.db 'PRAGMA database_list;'
  1. 6. Проверьте возможность создания журнала, а не только чтения файлаПосле резервной копии выполните тестовую запись только в отдельной копии базы, которую открывает тот же пользователь и в таком же каталоге по режиму доступа. Если чтение проходит, а запись нет, проверьте ACL, монтирование только для чтения, SELinux/AppArmor, свободные блоки и inode.
  2. Linux; проверяет место и inode
    Linux · Терминал (Bash)Команда
    Linux; проверяет место и inode. При нуле свободного места не запускайте VACUUM.
    df -h /srv/app/data && df -i /srv/app/data
  1. 7. Исправьте только подтверждённое ограничениеЕсли хозяин файла не совпадает после переноса, администратор должен назначить владельца конкретному файлу и каталогу по согласованной схеме. Для ACL дайте минимальные права целевому пользователю. Не меняйте защитные политики и владельцев всей системы вслепую.
  1. 8. Проверьте службу и откатПовторите чтение и штатную запись через приложение, затем проверьте журналы. Если ошибка осталась, верните исходные файлы/настройки по резервной копии и сопоставьте техническую учётную запись, конфигурацию подключения и журнал отказов.

#Как проверить исправление

Строка подключения указывает на существующий файл; запрос от реального пользователя процесса и контрольная запись приложения завершаются без ошибок, данные до переноса остались на месте.

#Если исправление не помогло

Если права соответствуют требованиям, изучите журнал отказов SELinux/AppArmor, варианты монтирования, ACL и возможный запрет open_basedir. Не устраняйте проблему глобальным chmod 777.

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

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

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