Почему нельзя вставить DBD :: SQLite в базу данных через мой Perl CGI-скрипт? - PullRequest
11 голосов
/ 14 июля 2009

Я использую базу данных SQLite в CGI-скрипте Perl, доступ к которому DBD :: SQLite . Это работает как прямой CGI на Apache.

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

DBD::SQLite::st execute failed: unable to open database file(1) at dbdimp.c line 402 at index.cgi line 66

Я попытался изменить разрешение файла базы данных на 666, чтобы попытаться это исправить, однако я все еще получаю сообщение об ошибке.

Любой совет?

Ответы [ 4 ]

22 голосов
/ 14 июля 2009

Похоже, что каталог требует разрешения на запись, причина:

SQLite должен иметь возможность создавать файл журнала в том же каталоге, что и БД, прежде чем будут иметь место какие-либо изменения. Журнал используется для поддержки отката транзакций.

From: , похоже, требуется разрешение на запись в родительский каталог базы данных

1 голос
/ 09 декабря 2012

Путь к каталогу, в котором находится файл db, должен содержать как исполняемые, так и записываемые биты, чтобы получить к нему доступ из скрипта.

Более того, если вам не нужен файл db чтобы иметь прямой доступ (даже без использования специальных файлов сервера), он должен иметь права доступа, такие как 600, и если содержащий каталог не должен просматриваться напрямую (опять же, даже без использования специальных файлов сервера), он должен иметь разрешения доступа например, 700.

Я использую эту настройку, и она отлично работает как локально, так и на сервере, где я размещаю свой сайт.

Разумеется, разрешение содержащейся директории не может быть 700, если внутри него есть какой-либо другой файл, который должен быть доступен через html, css или javascript. Вместо этого должно быть 755.

1 голос
/ 14 июля 2009

Поскольку SQLite блокирует весь файл базы данных, вы можете использовать механизм повтора на основе тайм-аута. Я работал над почти той же проблемой, когда задавал этот связанный вопрос .

Я закончил тем, что написал что-то похожее на Попытку Марка Фаулера , которая повторяет попытку, если исключение, выданное подпрограммой, соответствует регулярному выражению, в моем случае:

qr(already in a transaction|database is locked)i
1 голос
/ 14 июля 2009

SQLite на мгновение блокирует весь файл, когда он выполняет вставки и обновления (блокировка на уровне записи как таковая отсутствует). Вы уверены, что освобождаете замки?

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

...