我希望多台联网计算机上的多个进程通过OpenAFS 1.4.12.1同时访问同一个SQLite数据库。写入将不会频繁,因此SQLite的单写设计应该不是问题。
我想知道这是否可行。我很难找到两条重要的信息:
SQLite documentation声明"SQLite使用POSIX建议锁在Unix上实现锁定“。它还警告说,“你最好的防御是不要对网络文件系统上的文件使用SQLite”。但是,它似乎没有指定SQLite是只使用整个文件锁定,还是也使用字节范围锁定。
我也很难找出OpenAFS 1.4.12.1支持哪些类型的锁定。不幸的是,这个unofficial source from 1998是我所能找到的最好的资源。当时,支持全文件锁定,但不支持字节范围锁定。
官方文档只提到了this page,尽管它的标题很友好,但实际上并没有说明最新的OpenAFS是否支持POSIX字节范围建议锁定。
编辑:这是可能的吗?如果是这样,是否需要任何编译时SQLite标志?
发布于 2011-04-04 22:01:26
我使用SQLite已经有相当长的一段时间了,并且很幸运地处理了一些锁定问题。我非常确定SQLite在默认情况下在Unix文件系统上使用字节范围锁。
更准确地说,它包含了一些替代锁定方法的代码(例如,使用flock()和dotlock-style全文件锁)。使用SQLITE_ENABLE_LOCKING_STYLE option编译时,它会尝试自动检测底层文件系统的正确锁定方法。
自动检测代码包含一些硬编码的情况(例如"ufs“、"nfs”和"smbfs"),这些情况都不是AFS。如果没有匹配的硬编码大小写,SQLite将尝试使用fcntl()获取文件上的字节范围锁。然后,它假设如果fcntl()调用成功,那么字节范围锁是可用的。
这就是OpenAFS让事情变得有趣的地方。显然([1],[2],[3]) OpenAFS在字节范围锁的问题上向用户空间应用程序撒谎的历史由来已久。在openafs-1.4.14源代码中:
/* next line makes byte range locks always succeed,
* even when they should block */
if (af->l_whence != 0 || af->l_start != 0 || af->l_len != 0) {
DoLockWarning();
afs_PutFakeStat(&fakestate);
return 0;
}一句话:哦!
它允许字节范围锁在任何情况下都能成功。在Linux上,情况可能更糟:它使用内核基础设施在同一系统的进程之间提供字节范围锁。这意味着应用程序不能只是派生一个新进程并测试锁定机制-字节范围的锁看起来工作得很好,但却无法从远程进程中保护文件。
简而言之:您不能在OpenAFS中可靠地使用未修改的SQLite。大多数其他网络文件系统也有问题,因此建议完全避免使用网络文件系统。
以下是一些可能的变通方法,没有特定的顺序:
flock() on OpenAFS,那么在您的应用程序的long run.flock(),但只有在您使用OpenAFS用户空间而不是通过内核测试您自己的OpenAFS VFS it.无论您做什么,如果它以任何方式涉及SQLite3和共享数据库文件,您都必须执行广泛的测试。
编辑:
一位评论者建议使用点锁定文件机制。我没有深入研究过多的OpenAFS源代码,但乍一看它似乎支持创建SQLite使用的点锁文件的open(O_CREAT|O_EXCL)方法。如果它像预期的那样工作,那么如果您强制它使用点锁方法,那么SQLite确实可以与OpenAFS一起使用。
这就是说,在常规的本地文件系统上,点锁已经是一个足够的问题,而没有引入复杂的网络文件系统-这就是为什么我一开始就不建议这样做的原因。
https://stackoverflow.com/questions/5468349
复制相似问题