我读到 WAL 模式允许用户在写会话期间阅读。
因此我应该能够同时有 3 个会话读取数据和一个写入数据,这听起来对我来说是件好事,所以我想我应该定义会话类型,以便系统知道这个会话是读取器还是使用连接标志的编写器。
http://php.net/manual/en/sqlite3.open.php#refsect1-sqlite3.open-parameters
它在这里指出,如果会话没有完全关闭,则-shm
和-wal
文件不会被删除
https://www.sqlite .org/tempfiles.html#write_ahead_log_wal_files
在读取会话之后,临时文件不会被删除,这意味着尽管调用了 close 函数并返回会话并没有完全关闭true
,那么为什么使用SQLITE3_OPEN_READONLY
标志时文件没有被删除?我什至应该使用旗帜吗?
1 回答
您将 SQLite 的“读取器”和“写入器”概念与 PHP SQLite3 驱动程序以只读方式打开文件的能力混为一谈。
使用该SQLITE3_OPEN_READONLY
标志将导致 PHP 阻止所有写入操作并发出警告:
警告:SQLite3::exec():尝试在...中写入只读数据库
如果您想确保应用程序不会发生写入(可能作为安全措施),这可能很有用。但它与 SQLite 的读者和作者无关。
正如CL 所指出的,所有访问 WAL 模式数据库的进程都需要写访问权限。这是明确记录的:
此外,如果多个进程要访问 WAL 模式数据库,则所有进程都应在用户或组 ID 下运行,这些 ID 赋予它们对数据库文件、WAL 文件、共享内存 -shm 文件和包含目录的写访问权限。
并在该页面顶部提到了一个缺点:
无法打开只读 WAL 数据库。打开进程必须对与数据库关联的“-shm”wal-index 共享内存文件(如果该文件存在)具有写权限,或者如果“-shm”文件不存在,则对包含数据库文件的目录具有写权限。
SQLite 本身在接收到要执行的命令时决定进程是读取器还是写入器。例如,如果单个进程执行 a SELECT
,然后是 a INSERT
,然后是 a SELECT
,它会从 reader 变为 writer 到 reader。SQLite 将自动处理锁定(可能阻塞其他进程)。(请注意,这是一个简化的解释,不同的数据库操作模式可能会有很大的不同。)
出于您的目的,您不应使用该SQLITE3_OPEN_READONLY
标志。