在插入期间SQLite错误'尝试编写只读数据库'?

Aus*_*yde 117 sqlite permissions

我有一个SQLite数据库,我用于一个网站.问题是,当我尝试INSERT INTO它时,我会得到一个PDOException

SQLSTATE[HY000]: General error: 8 attempt to write a readonly database
Run Code Online (Sandbox Code Playgroud)

我通过SSH连接到服务器并检查权限,数据库具有权限

-rw-rw-r--
Run Code Online (Sandbox Code Playgroud)

我不熟悉*nix权限,但我很确定这意味着

  • 不是目录
  • 所有者具有读/写权限(根据我的说法ls -l)
  • 组具有读/写权限
  • 其他人只有读取权限

我也看到了我知道使用该sqlite3程序的所有地方,并没有发现任何相关内容.

因为我不知道PDO试图打开数据库的权限,我做到了

chmod o+w supplies.db
Run Code Online (Sandbox Code Playgroud)

现在,我得到另一个PDOException:

SQLSTATE[HY000]: General error: 14 unable to open database file
Run Code Online (Sandbox Code Playgroud)

但它只发生在我打开数据库尝试执行INSERT查询时.

关于发生了什么的任何想法?

Aus*_*yde 288

这个问题,因为它的出现,就是PDO SQLite的驱动程序要求,如果你打算做一个写操作(INSERT,UPDATE,DELETE,DROP,等),则数据库驻留在该文件夹必须具有写权限,以及实际数据库文件.

在PDO SQLite驱动程序手册页的最底部的注释中找到了这些信息.

  • 此外,SELinux(如果已安装)不得强制执行.花了我一天半的时间想出那一个. (9认同)
  • 据我所知,包含文件夹必须是可写的,因为在编写日志文件时会创建数据库本身.要使用户与Web服务器相同,请尝试将文件内容复制到另一个创建的ad hoc. (5认同)
  • 目前 sqlite3 可能有 3 个文件,`.db`、`.db-shm` 和 `.db-wal` 文件,当然还有这三个文件的父目录,对于运行 SQLite3 的用户来说,这些文件必须是可写的程序。 (5认同)
  • db文件和它所在的目录也必须由linux盒子上的'www-data'拥有. (4认同)

Cha*_*les 13

当SQLite文件的所有者本身与运行脚本的用户同时,就会发生这种情况.如果无法写入整个目录路径(意味着沿途的每个目录),则会发生类似的错误.

谁拥有SQLite文件?您?

脚本运行的是谁?Apache还是没人?

  • 啊,这让事情变得更有趣。如果您使用共享主机,则脚本很有可能以“nobody”或“apache”身份运行。让您的脚本创建一个文件(`file_put_contents('./foo.txt', 'Hello, world');`),该文件将显示它以谁的身份运行。您可能需要让脚本创建 SQLite 数据库。如果您当前文件中已有数据,这可能是一个有趣的练习...... (2认同)

小智 6

总之,我通过将数据库文件 (* .db) 放入子文件夹中解决了该问题。

  • 子文件夹及其中的数据库文件必须是 www-data 组的成员。
  • 在 www-data 组中,您必须具有写入子文件夹和数据库文件的权限。

####### 类似问题的附加说明 #####

我将我的 sqlite 数据库文件的写入权限授予其他用户和组,但它仍然不起作用。

文件位于我的 .NET Core WebApi 的 Web 根目录中。

它看起来像这样:

-rw-rw-rw-  1 root root  24576 Jan 28 16:03 librestore.db
Run Code Online (Sandbox Code Playgroud)

即使我以 root 身份运行该服务,我仍然收到错误:

错误:SQLite 错误 8:“尝试写入只读数据库”。

我还在 librestore.db 上对 www-data 进行了 chown,但仍然收到相同的错误。

最后,我移到了 webroot 目录之上,并授予其他人对该目录(LibreStore - 我的 WebApi 的根目录)的写入权限,然后它就工作了。

Web 根目录具有写入权限

我不确定如果特定文件已经具有写访问权限,为什么我必须授予目录写访问权限,但这是唯一有效的方法。

但是一旦我进行了更改,www-data用户就可以访问 .db 文件并且插入成功。


Noa*_*man 5

对我来说,问题是SELinux执行而不是权限.根据Steve V.在对已接受答案的评论中提出的建议,一旦我禁用了执法, "只读数据库"错误就消失了.

echo 0 >/selinux/enforce
Run Code Online (Sandbox Code Playgroud)

运行此命令后,一切都按预期工作(CentOS 6.3).

我遇到的具体问题是在Graphite的设置过程中.我已经三次检查了apache用户拥有并可以写入我的graphite.db及其父目录.但在我"修复"SELinux之前,我得到的只是一个堆栈跟踪效果:DatabaseError:尝试编写只读数据库

  • SELinux是一种安全措施,因此不应该在没有充分理由的情况下禁用.最好先弄清楚为什么SELinux会阻塞并正确配置它而不是禁用它. (6认同)

And*_*ley 5

这可能是由 SELinux 引起的。如果不想完全禁用SELinux,则需要将db目录fcontext设置为httpd_sys_rw_content_t。

semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/railsapp/db(/.*)?"
restorecon -v /var/www/railsapp/db
Run Code Online (Sandbox Code Playgroud)