11

我在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 以尝试解决此问题,但我仍然收到错误消息。

有什么建议吗?

4

5 回答 5

23

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

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

来自:似乎需要对 db 的父目录的写权限

于 2009-07-14T02:26:24.380 回答
1

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

SQLite 文献建议您启动一个事务,收集该事务中的所有插入和更新,然后提交。这避免了许多连续的文件锁定,并提高了性能。

于 2009-07-14T00:45:28.120 回答
1

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

我最终写了类似于 Mark Fowler 的尝试,如果子抛出的异常与正则表达式匹配,则重试,在我的例子中:

qr(already in a transaction|database is locked)i
于 2009-07-14T12:45:43.603 回答
1

db 文件所在目录的路径应该同时设置可执行位和可写位,以便从脚本中访问它。

此外,如果您不想直接访问 db 文件(即使不使用特殊的服务器文件),它应该具有 600 等访问权限,并且如果不应该直接浏览包含的目录(同样,即使没有使用特殊的服务器文件)它应该具有访问权限,例如 700。

我使用此设置,它在本地和托管我的站点的服务器上都可以正常工作。

当然,如果包含目录中存在任何其他应该可以通过 html、css 或 javascript 访问的文件,则包含目录的权限不能为 700。它应该是 755。

于 2012-12-08T22:17:37.477 回答
0

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

在这种情况下,请注意:

MEMORY 日志模式将回滚日志存储在易失性 RAM 中。这节省了磁盘 I/O,但以牺牲数据库安全性和完整性为代价。如果在设置 MEMORY 日志模式时使用 SQLite 的应用程序在事务中间崩溃,那么数据库文件很可能会损坏。

所以这是否是一个好的解决方案取决于你的数据库以及它是如何使用的。

其他人也提到了temp_store 杂注。我不需要设置它,但这可能取决于数据库的使用方式。

所以在你的 Perl CGI 脚本中,你可以试试这个:

$dbh->do("PRAGMA journal_mode = MEMORY");
$dbh->do("PRAGMA temp_store   = MEMORY");
于 2019-11-20T19:47:45.293 回答