SQLite与OpenAFS锁定兼容吗?

前端之家收集整理的这篇文章主要介绍了SQLite与OpenAFS锁定兼容吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想在许多联网计算机上有许多进程同时通过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标志?

解决方法

我已经使用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.大多数其他网络文件系统也存在问题,因此建议完全避免使用网络文件系统.

一些可能的解决方法没有特定的顺序:

>使用适当的DBMS,例如PostgreSQL.如果可以这样做,从长远来看,你会更好.
>如果完整的DBMS过度,则为您的应用程序实现自己的服务器.
>在OpenAFS上将sqlite源代码修改为默认为flock().我不确定这是否会正常工作,因为OpenAFS有很长的历史记录([1],[2]),即使是普通的flock(),也有锁定问题,但在测试之前你不会知道.
>使用OpenAFS用户空间为sqlite实现自己的OpenAFS VFS,而不是通过内核.
>试试你的运气与另一个网络文件系统.

无论您做什么,如果以任何方式涉及sqlite3和共享数据库文件,您都必须执行大量测试.

编辑:

一位意见提供者建议使用dotlock文件机制.我没有太多深入研究OpenAFS源代码,但乍一看它似乎支持创建sqlite使用的dotlock文件open(O_CREAT|O_EXCL)方法.如果它按预期工作,那么如果强制它使用dotlock方法,则sqlite可能确实可用于OpenAFS.

也就是说,dotlocks足以解决常规本地文件系统的问题,而不会将网络文件系统的复杂性引入混合中 – 这就是为什么我首先没有提出它的原因.

猜你在找的Sqlite相关文章