#Что происходит и когда инструкция применима
Ошибка SQLite disk I/O error при записи в SMB/NFS-каталог часто связана с особенностями блокировок и сетевого доступа. Нужно отличить сеть от физической ошибки диска, сверить путь монтирования и перенести рабочую SQLite-базу на поддерживаемое локальное хранилище.
Характерный признак: База на сетевой папке периодически выдаёт SQLITE_IOERR, иногда SQLITE_BUSY; при том же приложении и базе на локальном диске запись стабильнее.
#Как отличить возможные причины
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Сетевые блокировки ненадёжныSQLite опирается на согласованные блокировки и операции файловой системы | Сбои возникают при двух хостах | Выделить единственный локальный сервер |
| WAL расположен на сетевом дискеРазделяемая память -shm не предназначена для доступа разных хостов | Появляется -wal/-shm на SMB/NFS | Не использовать WAL на общем сетевом томе |
| Сеть или диск теряет I/OТайм-ауты монтирования или ошибка NAS вызывают неполную операцию | В dmesg/journalctl есть I/O или reconnect | Диагностировать хранилище |
#Пошаговая диагностика и исправление
- 1. Зафиксируйте точный расширенный код ошибкиНайдите ошибку в журнале приложения и время возникновения. SQLSTATE или «disk I/O error» недостаточны для установления причины; если драйвер выдаёт расширенный код SQLITE_IOERR_*, сохраните его.
- 2. Проверьте, где фактически находится файлНа Linux выполните findmnt для каталога базы. Если тип nfs, cifs или иной сетевой, зафиксируйте его и сервер хранения; вывод только описывает монтирование.Linux · Терминал (Bash)КомандаПуть изменить на реальный. Результат покажет локальный раздел или сетевой тип. Не перемонтируйте боевой том.
findmnt -T /mnt/shared/app.db -o TARGET,SOURCE,FSTYPE,OPTIONS
- 3. Посмотрите сетевые и дисковые событияАдминистратору Linux нужно проверить журнал ядра за период ошибки: reconnect, stale file handle, I/O error, read-only. При проблемах сети сначала устраните их в инфраструктуре.
- Linux с systemd; tail только ограничивает выводLinux · Терминал (Bash)КомандаLinux с systemd; tail только ограничивает вывод. Может требовать доступ к системному журналу.
journalctl -k --since '1 hour ago' --no-pager | tail -n 80
- 4. Проверьте, кто ещё открывает базуУточните число серверов и процессы, которые обращаются к одному SQLite-файлу. В режиме WAL процессы должны работать на одном хосте; доступ с разных машин через общую папку не поддерживается.
- 5. Получите согласованную копию через штатное приложениеЕсли SQLite продолжает читать исходник, сделайте резервную копию API и убедитесь в integrity_check на отдельном локальном диске. При I/O ошибках сперва обеспечьте сохранность исходных файлов и обратитесь к администратору хранилища.
- Проверяет уже созданную локальную копию, а не сетевой оригиналLinux · Терминал (Bash)КомандаПроверяет уже созданную локальную копию, а не сетевой оригинал. Ожидается ok.
sqlite3 -readonly /srv/local/backups/app-copy.db 'PRAGMA integrity_check;'
- 6. Проверьте поведение на локальной тестовой копииРазверните согласованную копию на локальном SSD серверного приложения; запустите тестовое приложение с тем же SQL, но отдельными учётными данными и путём. Если сбой исчез, подтвердите первичность сетевого размещения.
- 7. Выберите безопасную архитектуру для нескольких хостовЕсли приложение запущено на разных серверах, не делайте общую SQLite-базу по SMB/NFS основным местом записи. Выделите один процесс-сервис, который владеет локальной базой, либо используйте СУБД клиент-сервер (PostgreSQL/MySQL).
- 8. Переключите только после тестов и возможности откатаПосле согласования окна записи и полного бэкапа обновите путь подключения приложения. Повторите чтение и запись; при ошибке остановите тест и вернитесь к исходной конфигурации без параллельной записи в две копии.
#Как проверить исправление
На новом локальном размещении нет SQLITE_IOERR при повторе штатной операции; целостность ok, важные записи сохранены, логи файловой системы спокойны.
#Если исправление не помогло
Если локальная база также выдаёт ошибку, проверяйте свободное место, inode, питание и исправность накопителя; требуется анализ расширенного кода SQLITE_IOERR.