Назад | Перейти на главную страницу

Непоследовательная ошибка «невозможно открыть файл базы данных» из программы CGI, использующей SQLite

Я бегал целевая программа для психологического эксперимента на моем виртуальном частном сервере с lighttpd 1.4.28 и Ubuntu 12.04. Эксперимент представляет собой программу CGI, написанную на Perl с использованием модуль Perl, который я написал, представляя веб-интерфейс через Mechanical Turk. Данные хранятся в базе данных SQLite с использованием режима WAL, а DBD :: SQLite обеспечивает базовый интерфейс Perl.

Эксперимент, кажется, работает нормально для большинства рабочих, завершающих его на Mechanical Turk. Однако иногда пользователи получают ошибку DBD::SQLite::db prepare failed: unable to open database file. Это происходит в кажущиеся произвольными точках в середине выполнения задачи, которая включает в себя щелчок по примерно 100 HTML-страницам, созданным программой CGI, каждая из которых попадает в базу данных. Кажется, он не исчезает, когда пользователи обновляют страницу (я считать). Я понятия не имею, как воспроизвести его самостоятельно, но я точно знаю, что он поразил как минимум 2 из 15 пользователей. Смотря на top в то время как это происходило, похоже, что процессор и память не подвергались нагрузке. Дисковое пространство тоже не проблема (я использую только 1,4 гигабайта 3-гигабайтного раздела). База данных в настоящее время составляет около 280 КБ. PRAGMA integrity_check; вернулся ok.

Есть идеи, как это отладить? Google сообщает мне, что «невозможно открыть файл базы данных» обычно является ошибкой разрешений или чем-то в этом роде, но все это настроено правильно; задача обычно работает.

Эта ошибка может произойти, когда SQLite не может создать временный файл. (В этой ситуации «файл базы данных» в сообщении об ошибке немного вводит в заблуждение.)

Например, это происходит в Windows, если SQLite необходимо записать временную таблицу / индекс на диск, и ни одна из переменных окружения TMP, TEMP, USERPROFILE не установлена. В этом случае SQLite пытается создать временный файл в каталоге Windows, что обычно не допускается. Это можно исправить, передав TEMP скрипту (в конфигурации Apache, PassEnv "TEMP") или внутри скрипта, указывая $ENV{TEMP} в подходящий каталог.

Создание временного файла может завершиться ошибкой по другим причинам. См. Функции «unixGetTempname» и «winGetTempname» в источниках SQLite, чтобы узнать точные правила, которые SQLite использует для поиска временного каталога на вашей платформе.