在NFS文件系统上锁定sqlite文件是否可行?

14

假设有两个Python脚本想要使用sqlite3模块将数据写入存储在SQLite文件中的同一张表。SQLite文件存储在NFS文件系统上。我在SQLite-FAQ中读到:

SQLite使用读取器/编写器锁来控制对数据库的访问。 [...] 但要小心:如果数据库文件保存在NFS文件系统上,则此锁定机制可能无法正常工作。这是因为 许多NFS实现都存在fcntl()文件锁定问题。如果有多个进程可能尝试同时访问该文件,则应避免将SQLite数据库文件放在NFS上。

这是否意味着根本不可能实现,还是有某种方法可以确保一个进程等待另一个进程完成?

这些INSERT不复杂,只有一些:

INSERT_STATEMENT = "INSERT INTO some_table (row, col, val) VALUES (?, ?, ?)"
connection.executemany(INSERT_STATEMENT, triples)

而且插入的集合是不相交的。

进一步的问题:NFS问题是否发生在两个进程尝试写入同一个表时或者当他们尝试写入同一个数据库(即文件)时?让每个进程在同一个数据库(文件)中创建自己的表并写入这个表,这是否是一个解决方法?

1个回答

24

不要在NFS上使用SQLite。就是这么简单。NFS的语义与常规文件系统不同,并且更加松散。你最终会遇到数据损坏问题。SQLite用户邮件列表中偶尔会有人发布他们的“解决方法”。虽然短期内似乎有效,但实际上永远不起作用。


1
很不幸,我必须使用SQLite。最后我给每个进程分配了自己的文件来写入,并在之后合并这些脚本。但还是谢谢你的回答!:-) - Aufwind
4
当你最终遇到文件损坏时,请确保提及你使用了NFS。不要感到惊讶,当所有人的回应都是“不要这样做”时。 - Roger Binns
1
即使只有一个进程访问该文件,也不要这样做。 - user445107
1
你需要完美的代码和流程,才能绝对确保在任何情况下都没有并发访问。如果你有一丝不苟的失误,就会出现不为人知的损坏,最终你会发现已经太晚了。 - Roger Binns
1
听起来答案可能更像是“如果NFS实现正确地执行X、Y和Z,那么这是可能的,但有些实现并没有做到”。例如,https://aws.amazon.com/about-aws/whats-new/2017/03/amazon-elastic-file-system-amazon-efs-now-supports-nfsv4-lock-upgrading-and-downgrading/提到EFS(AWS NFS实现)现在支持NFSv4锁升级和降级,并特别提到了SQLite。这似乎解决了关于锁定的警告。是否还有一些SQLite依赖的其他文件系统语义对于某些NFS实现来说不稳定?如果有,是什么? - pchiusano
在正常情况下(实际上几乎所有的东西都是如此),NFS 将会正常工作。但是当出现问题时,将会涉及到两个或更多系统,并且每次相互交互时都必须完全正确。这种情况很难实现,这也是 SQLite 团队继续建议不要使用网络文件系统的原因之一。还有其他解决方案,比如使用 litestream.io 等进行 SQLite 数据库的网络共享。 - Roger Binns

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接