Почему DBD :: SQLite не может вставить в базу данных мой сценарий Perl CGI?

Я запускаю базу данных SQLite в Perl CGI-скрипте, к которому обращается 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, чтобы попытаться исправить это, но я все еще получаю сообщение об ошибке.

Любой совет?


person Todd Hunter    schedule 14.07.2009    source источник
comment
Можете ли вы временно установить для каталога и файла разрешение 777 и перепроверить его?   -  person Henrik P. Hessel    schedule 14.07.2009
comment
Ага! Изменение прав доступа к каталогу на 777 исправило это. Вы знаете, почему это так?   -  person Todd Hunter    schedule 14.07.2009
comment
Вы, вероятно, тоже забыли установить правильные права доступа к каталогу.   -  person Henrik P. Hessel    schedule 14.07.2009


Ответы (5)


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

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

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

person Todd Hunter    schedule 14.07.2009

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

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

person Robert Harvey    schedule 14.07.2009

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

В итоге я написал что-то похожее на попытку Марка Фаулера, которая повторяет попытку, если возникло исключение. by sub соответствует регулярному выражению, в моем случае:

qr(already in a transaction|database is locked)i
person hillu    schedule 14.07.2009

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

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

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

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

person sadesyllas    schedule 08.12.2012

Если вы не хотите устанавливать разрешения на запись для всего каталога, как описано в ответе Тодда Хантера, вы можете вместо этого установить _ 1_ PRAGMA в" ПАМЯТЬ ".

В этом случае помните, что:

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

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

Другие также упоминают прагму temp_store. Мне не нужно было это устанавливать, но это может зависеть от того, как используется база данных.

Итак, в своем Perl CGI-скрипте вы можете попробовать следующее:

$dbh->do("PRAGMA journal_mode = MEMORY");
$dbh->do("PRAGMA temp_store   = MEMORY");
person mivk    schedule 20.11.2019