为什么DBD :: SQLite无法通过我的Perl CGI脚本插入数据库?

问题描述 投票:11回答:5

我正在DBD::SQLite访问的Perl CGI脚本中运行SQLite数据库。它正在Apache上作为直接CGI运行。

DBI连接可以正常工作,并且可以运行选择。但是,当我尝试插入时,出现以下错误:

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

我已经尝试将数据库文件权限更改为666,以尝试解决此问题,但是我仍然收到错误。

有什么建议吗?

perl apache sqlite dbi
5个回答
23
投票

看起来目录需要写权限,原因是:

SQLite必须能够在与数据库相同的目录中创建日记文件,然后才能进行任何修改。该日志用于支持事务回滚。

发件人:seem to need write permission on db's parent directory


1
投票

SQLite在执行插入和更新时会暂时锁定整个文件(没有这样的记录级锁定)。您确定要释放锁吗?

SQLite文献建议您启动事务,在该事务中收集所有插入和更新,然后再提交。这样可以避免大量连续的文件锁定,并提高了性能。


1
投票

由于SQLite锁定了整个数据库文件,因此您可能希望使用基于超时的重试机制。当我问这个相关的question时,我正在处理几乎相同的问题。

我最终写出了类似于Mark Fowler的Attempt的东西,如果子程序抛出的异常与正则表达式匹配,则重试qr(already in a transaction|database is locked)i

journal_mode

1
投票

db文件所在目录的路径应同时设置可执行位和可写位,以便从脚本中访问它。此外,如果您不希望直接访问db文件(即使不使用特殊的服务器文件),它也应具有600的访问权限,并且不应该直接浏览包含目录(同样,即使没有使用特殊的服务器文件),它应该具有700的访问权限。我使用此设置,并且在本地以及托管我的网站的服务器上都可以正常工作。当然,如果其中包含任何其他文件可以通过html,css或javascript访问,则包含目录的权限不能为700。应该是755。


0
投票

如果您不想按照Todd Hunter的回答中所述对整个目录设置写权限,则可以将journal_mode PRAGMA设置为“ MEMORY”。

在这种情况下,请注意:

MEMORY日记记录模式将回滚日记存储在volatile中内存。这样可以节省磁盘I / O,但要以牺牲数据库安全性和诚信。如果使用SQLite的应用程序在中间崩溃设置MEMORY日记记录模式时进行事务处理,然后数据库文件很可能会损坏。

因此,这是否是一个好的解决方案,取决于您的数据库及其使用方式。

[其他人也提到temp_store pragma。我不需要进行设置,但这可能取决于数据库的使用方式。

因此,在您的Perl CGI脚本中,您可以尝试以下操作:

$dbh->do("PRAGMA journal_mode = MEMORY");
$dbh->do("PRAGMA temp_store   = MEMORY");
© www.soinside.com 2019 - 2024. All rights reserved.