【问题标题】:SQLite VACUUM in DB opened from multiple processes从多个进程打开的数据库中的 SQLite VACUUM
【发布时间】:2017-09-14 21:08:51
【问题描述】:

我有两个关于 SQLite VACUUM(可能还有 WAL)的问题:

• 如果多个进程都打开了 DB,是否需要完成所有进程中的所有 SQL 语句才能使 VACUUM 成功?

• 为什么 VACUUM 有时没有效果(没有回收空间)但 Sqlite 返回 SQLITE3_OK?

关于我的问题的更多细节:

我有 2 个进程访问的 WAL 模式下的数据库。在某些时候,用户可以选择从数据库中删除数据。因为数据库可以被多个进程打开,所以我删除了记录,然后运行 ​​VACUUM 来回收磁盘空间(而不是关闭连接并删除文件)。

问题是,如果 2 个进程打开了 DB 连接,则其中一个进程的 VACUUM 返回 OK,但并没有真正回收空间。

我认为会发生的情况是 VACUUM 不会成功,除非任何进程有任何未完成的 SQL 语句。问题是我不想让这两个进程相互了解。

我正在考虑从两个进程中执行 VACUUM,以便最后关闭连接的那个(根据用户请求删除数据)负责空间回收。我也在考虑使用 auto_vacuum(我知道它的局限性,但 DELETE 在这个数据库上并不是很频繁。

【问题讨论】:

    标签: sqlite


    【解决方案1】:

    documentation 说:

    如果有一个打开的事务,或者在运行时有一个或多个活动的 SQL 语句,则 VACUUM 将失败。

    与任何其他类型的数据库修改一样,可写事务要求没有其他读写事务处于活动状态;这通常需要重置或完成所有语句。

    在 WAL 模式下,写入事务不会被其他读取事务阻塞,但这需要保留旧数据。除了真空,你应该initiate a truncate checkpoint


    处理这个问题的最简单方法是根本不运行 VACUUM;空闲空间将在以后重复使用。

    【讨论】:

    • 想知道为什么调用真空时没有 SQLite 错误仍然很有趣。
    • 如果它返回 SQLITE_OK,它确实做了一个真空。
    • 磁盘上的文件大小保持不变,检查了很多次。
    • 并且,仅当涉及 2 个进程时。返回码在这两种情况下都可以,这是所有这些混乱的核心。我希望数据库被锁定或其他东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 2016-07-21
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多