我在Perl CGI脚本中运行SQLite数据库,DBD::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以尝试修复此问题,但我仍然收到错误。
有什么建议吗?
答案 0 :(得分:22)
看起来目录需要写权限,原因是:
在进行任何修改之前,SQLite需要能够在与DB相同的目录中创建日志文件。该期刊用于支持交易回滚。
答案 1 :(得分:1)
SQLite在执行插入和更新时会暂时锁定整个文件(没有记录级锁定)。你确定你正在释放锁吗?
SQLite文献建议您启动事务,收集该事务中的所有插入和更新,然后提交。这避免了许多连续的文件锁定,并提高了性能。
答案 2 :(得分:1)
由于SQLite锁定整个数据库文件,您可能希望使用基于超时的重试机制。当我问这个相关的question时,我正在研究几乎相同的问题。
我最后写了一些类似于Mark Fowler的Attempt的东西,如果sub抛出的异常与正则表达式匹配,我会重试:在我的情况下:
qr(already in a transaction|database is locked)i
答案 3 :(得分:1)
db文件所在目录的路径应设置可执行和可写位,以便从脚本中访问它。
此外,如果你不想要db文件要直接访问(即使没有使用特殊的服务器文件),它应具有访问权限,如600,如果不应直接浏览包含目录(再次,即使不使用特殊服务器文件),它应具有访问权限例如700.
我使用这个设置,它在本地和我托管我的网站的服务器上工作正常。
当然,包含目录的权限不能如果其中有任何其他文件应该可以通过html,css或javascript访问,则为700。它应该是755而已。
答案 4 :(得分: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");