SQLite 与 OpenAFS 锁定兼容吗?
我希望许多联网计算机上的许多进程同时通过 OpenAFS 1.4.12.1 访问同一个 SQLite 数据库。写入不会频繁,因此 SQLite 的单次写入设计应该不会有问题。
我想知道这是否可行。我无法找到两个关键信息:
SQLite 文档 指出“SQLite 使用 POSIX Advisory locks 在 Unix 上实现锁定”。它还警告“最好的防御是不要对网络文件系统上的文件使用 SQLite”。然而,它似乎没有指定 SQLite 是否仅使用整个文件锁定,或者是否也使用字节范围锁定。
我也无法找出 OpenAFS 1.4.12.1 支持哪些类型的锁定。不幸的是,这个1998年的非官方来源是我最好的来源已经能够找到了。当时,支持整个文件锁定,但不支持字节范围锁定。
官方文档只显示此页面,尽管标题很友好,但实际上并没有说明是否最新的 OpenAFS 支持 POSIX 字节范围咨询锁定。
编辑: 这有可能吗?如果是这样,是否需要任何编译时 SQLite 标志?
I would like to have many processes on many networked computers simultaneously access the same SQLite database via OpenAFS 1.4.12.1. Writes will be infrequent, so the single-write design of SQLite should not be a problem.
I would like to know if this is feasible. I am having trouble locating two crucial pieces of information:
The SQLite documentation states that "SQLite uses POSIX advisory locks to implement locking on Unix". It also warns that "Your best defense is to not use SQLite for files on a network filesystem". However, it does not seem to specify whether SQLite uses only whole-file locking, or whether it also uses byte-range locking.
I am also having trouble finding out which types of locking OpenAFS 1.4.12.1 supports. This unofficial source from 1998 is unfortunately the best source I have been able to find. Back then, whole-file locking was supported but byte-range locking was not.
The official documentation turns up only this page, which despite it's friendly title actually says nothing about whether POSIX byte-range advisory locking is supported by the latest OpenAFS.
EDIT:
Is this possible at all? If so, are any compile-time SQLite flags needed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我已经使用 SQLite 相当长一段时间了,并且有幸处理过一些锁定问题。我非常确定 SQLite 默认情况下在 Unix 文件系统上使用字节范围锁。
更准确地说,它包含一些替代锁定方法的代码(例如使用
flock()
和 dotlock-style 整个文件锁)。当使用SQLITE_ENABLE_LOCKING_STYLE
选项编译时,它会尝试自动检测正确的底层文件系统的锁定方法。自动检测代码包含一些硬编码的情况(例如“ufs”、“nfs”和“smbfs”),其中没有一个是AFS。如果没有硬编码的大小写匹配,SQLite 会尝试使用
fcntl()
。然后,它假设如果 fcntl() 调用成功,则字节范围锁可用。这就是 OpenAFS 让事情变得有趣的地方。显然([1],[2], [3]) OpenAFS 在字节范围锁方面向用户空间应用程序撒谎的历史悠久。来自
openafs-1.4.14
源代码:一句话:哎呀!
无论如何,它都允许字节范围锁定成功。在 Linux 上,情况可能更糟:它使用内核基础设施在同一系统的进程之间提供字节范围锁。这意味着应用程序不能只是分叉一个新进程并测试锁定机制 - 字节范围锁看起来工作正常,但在保护文件免受远程进程侵害方面却严重失败。
简而言之:您无法通过 OpenAFS 可靠地使用未经修改的 SQLite。大多数其他网络文件系统也存在问题,因此建议完全避免使用网络文件系统。
一些可能的解决方法(排名不分先后):
使用适当的 DBMS,例如 PostgreSQL。如果可以做到这一点,从长远来看,您的情况会更好。
如果成熟的 DBMS 太过分了,请为您的应用程序实现您自己的服务器。
修改 SQLite 源代码以默认为 OpenAFS 上的
flock()
。我不确定这是否能正常工作,因为 OpenAFS 有着悠久的历史 ([1]、[2] )的锁定问题,即使使用普通的flock()
,但在测试之前您不会知道。使用 OpenAFS 用户空间,而不是通过内核,为 SQLite 实现您自己的 OpenAFS VFS。
用另一个网络文件系统试试你的运气。
无论您做什么,如果以任何方式涉及 SQLite3 和共享数据库文件,您都必须执行大量测试。
编辑:
评论者建议使用点锁文件机制。我没有深入研究 OpenAFS 源代码,但乍一看它似乎支持 < code>open(O_CREAT|O_EXCL) 创建 SQLite 使用的点锁文件的方法。如果这按预期工作,那么如果您强制 SQLite 使用点锁方法,那么 SQLite 可能确实可以与 OpenAFS 一起使用。
也就是说,点锁在常规本地文件系统上已经足够成为一个问题,而无需将网络文件系统的复杂性引入其中 - 这就是为什么我一开始没有建议它。
I have been using SQLite for quite some time and have had the "fortune" of dealing with some locking issues. I am pretty certain that SQLite uses byte-range locks on Unix filesystems by default.
To be more precise, it contains code for a few alternative locking methods (e.g using
flock()
and dotlock-style whole-file locks). When compiled with theSQLITE_ENABLE_LOCKING_STYLE
option it attempts to auto-detect the proper locking method for the underlying filesystem.The auto-detection code contains some hard-coded cases (e.g. "ufs", "nfs" and "smbfs"), none of which is AFS. If no hard-coded case matches, SQLite attempts to acquire a byte-range lock on a file using
fcntl()
. It then assumes that if thefcntl()
call succeeds, then byte-range locks are available.Here is where OpenAFS comes in to make things interesting. Apparently ([1], [2], [3]) OpenAFS has a long history of lying to the userspace applications about byte-range locks. From the
openafs-1.4.14
source code:In one word: Ouch!
It allows byte-range locks to succeed no matter what. On Linux, it is conceivably even worse: it uses the kernel infrastructure to provide byte-range locks among the processes of the same system. That means that an application cannot just fork a new process and test the locking mechanism - byte-range locks will appear to be working fine, while failing horribly to protect a file from remote processes.
In short: you cannot use an unmodified SQLite reliably with OpenAFS. Most other network filesystems have issues as well, hence the recommendation to avoid network filesystems completely.
A few possible work-arounds in no particular order:
Use a proper DBMS, such as PostgreSQL. If it is possible to do this, you'll be better off in the long run.
Implement your own server for your application, if a full-blown DBMS is overkill.
Modify the SQLite source code to default to
flock()
on OpenAFS. I am not sure if this will work properly, since OpenAFS has a long history ([1], [2]) of locking issues even with plain-oldflock()
, but you won't know until you test it.Implement your own OpenAFS VFS for SQLite, using the OpenAFS userspace, rather than going through the kernel.
Try your luck with another network filesystem.
Whatever you do, you will have to perform extensive testing if in any way it involves SQLite3 and a shared database file.
EDIT:
A commenter suggested using the dotlock file mechanism. I didn't delve into the OpenAFS source code too much, but at first glance it appears to support the
open(O_CREAT|O_EXCL)
method of creating dotlock files that SQLite uses. If that works as it is supposed to, then SQLite might indeed be usable with OpenAFS if you force it to use the dotlock method.That said, dotlocks are enough of a problem on regular local filesystems, without introducing the intricacies of a network filesystem into the mix - which is why I did not suggest it in the first place.