Hacker News 中文摘要

RSS订阅

SQLite(使用WAL)在默认设置下不会每次提交都执行`fsync` -- SQLite (with WAL) doesn't do `fsync` on each commit under default settings

文章摘要

SQLite在WAL模式下默认使用synchronous=NORMAL,不会在每次提交时调用fsync,这可能导致事务在断电或系统崩溃后回滚。若需确保每次提交的持久性,应设置synchronous=FULL,此时每次提交后会额外同步WAL文件,增强事务的持久性。

文章总结

标题: SQLite(使用WAL模式)在默认设置下不会在每次提交时执行fsync

主要内容: SQLite提供了WAL(Write-Ahead Logging)模式,该模式默认情况下不会在每次提交时调用fsync操作。WAL模式通常用于提高写入吞吐量。SQLite的PRAGMA synchronous配置项用于控制fsync的调用方式,默认值为NORMAL。在NORMAL模式下,WAL文件在每次检查点之前同步,数据库文件在每次检查点完成后同步,WAL文件头在检查点后重新使用时同步,但在大多数事务期间不会执行同步操作。这意味着在NORMAL模式下,事务在电源丢失或系统崩溃后可能会回滚,从而影响数据的持久性。

如果需要在每次提交时调用fsync,可以将PRAGMA synchronous设置为FULL。在FULL模式下,每次事务提交后都会额外同步WAL文件,以确保事务在电源丢失时仍然持久。

更新: 文章作者最初认为默认的SQLite3在macOS上的行为是PRAGMA synchronous=1,但通过Homebrew安装的SQLite3版本显示PRAGMA synchronous=2。此外,编译时选项SQLITE_DEFAULT_SYNCHRONOUSSQLITE_DEFAULT_WAL_SYNCHRONOUS可以设置默认的同步模式,如果没有在编译时覆盖,默认值为FULL(即2)。

相关讨论: 有人向作者推荐了一篇关于SurrealDB牺牲数据持久性以优化基准测试的文章,并询问SQLite的工作原理。

评论总结

评论主要围绕SQLite的默认设置、性能与数据持久性之间的权衡展开,以下是总结:

  1. 默认设置与性能

    • SQLite默认使用FULL同步模式,但某些包装器可能会更改默认设置(评论5)。
    • 默认设置可能出于性能考虑,但现代SSD的频繁fsync可能会影响其寿命(评论2)。
  2. 数据持久性与应用场景

    • 在嵌入式数据库中,电源丢失可能导致应用和SQLite同时“忘记”已提交的数据,因此默认设置是合理的(评论3)。
    • 对于客户端应用,SQLite默认是FULL同步,而SurrealDB作为远程服务器默认关闭fsync,两者场景不同(评论11)。
  3. 文档与用户责任

    • SQLite的文档清晰,用户应理解其行为并根据应用需求调整设置(评论3, 评论12)。
    • 默认设置应优先保证安全,而非性能,用户不应假设所有默认设置都是安全的(评论7)。
  4. WAL模式的限制

    • WAL模式需要所有客户端共享内存,并且会禁用附加数据库的ACID事务,启用前需充分理解其限制(评论6)。
  5. 具体使用建议

    • 在Apple平台上,建议使用F_FULLFSYNC而非fsync以确保数据持久性(评论1)。
    • 使用Lightstream时,文档建议使用synchronous=NORMAL,但用户应根据需求决定是否恢复为FULL(评论13)。

总结:SQLite的默认设置在不同场景下有其合理性,用户应根据具体需求理解并调整相关配置,确保数据安全与性能的平衡。