为什么SQLite3在Amazon弹性文件系统上无法工作?

5
当我尝试在EFS目录上使用sqlite3创建一个基础时,会出现错误: $ sqlite3 foo.db SQLite version 3.7.17 2013-05-20 00:56:22 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .log stderr sqlite> CREATE TABLE foo (int bar); Error: disk I/O error 所涉及的Sqlite3数据库仅用于存储元数据,并且将不经常更新。不需要并发访问。但是,如果创建数据库的进程死亡,则需要在不同的主机上重新启动进程,并在先前实例退出的地方继续执行。
Amazon声称EFS是“通过文件系统接口(使用标准操作系统文件I / O API)可访问的文件系统,并支持完整的文件系统访问语义(例如强一致性和文件锁定)”。因此,我认为它适合手头的任务。 /etc/fstab中的挂载选项为:

eu-west-1a.fs-ID.efs.eu-west-1.amazonaws.com:/ /efs nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 0 0

我理解通常不建议将数据库放在NFS上。然而,考虑到亚马逊和SQLite所使用的语言,开发人员仍会尝试。


使用.log stderr获取更多的错误信息。 - CL.
@CL。.log stderr 不会产生任何附加输出。 - Jan
在你尝试写任何东西之前。 - CL.
@CL。我明白了,看到我上面的编辑了吗?这就是我得到的结果。 - Jan
请更新您的 sqlite3 工具。 - CL.
使用 strace 命令跟踪进程,以查看涉及的系统调用。就我所观察到的而言,EFS 似乎使用非常大(>32位)的 inode 号码。 - Michael - sqlbot
2个回答

6

更新(2017年3月6日):

EFS现在支持NFS v4.1锁的升级和降级:

https://aws.amazon.com/about-aws/whats-new/2017/03/amazon-elastic-file-system-amazon-efs-now-supports-nfsv4-lock-upgrading-and-downgrading/

来自文档:

锁的升级和降级:如果客户端尝试升级或降级现有锁定,则Amazon EFS会返回NFS4ERR_LOCK_NOTSUPP。

注意

由于不支持锁的升级和降级,因此使用需要此功能的用例(例如使用SQLite或IPython的用例)也不支持Amazon EFS。

请参阅:

http://docs.aws.amazon.com/efs/latest/ug/efs-ug.pdf

还有:

http://docs.aws.amazon.com/efs/latest/ug/nfs4-unsupported-features.html


1
EFS现在支持锁定升级和降级。请参见https://aws.amazon.com/about-aws/whats-new/2017/03/amazon-elastic-file-system-amazon-efs-now-supports-nfsv4-lock-upgrading-and-downgrading/。 - user1071840
1
感谢@user1071840,我很高兴听到这个对我的用例也有帮助。我会更新我的答案,以免误导那些找到它的人。 - 2tim
1
我在我的AWS设置中仍然遇到了这个问题,你在EFS/Grafana设置中定义了什么特殊的东西来使它工作吗? - koby meir
听起来像是需要向AWS支持团队提问的问题。 - 2tim

5

默认情况下,sqlite在“unix”VFS上运行,它使用Amazon EFS不支持的锁升级。但是,如果您将VFS更改为“unix-excl”,则可以在Amazon EFS上使用sqlite数据库,该VFS使用独占文件锁并且不需要升级。

有几种指定VFS的方法。如果您正在使用命令行,请添加“-vfs unix-excl”选项:

ubuntu@ip-1-1-1-1 /efs> sqlcipher foo.db -vfs unix-excl
SQLCipher version 3.8.10.2 2015-05-20 18:17:19
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> CREATE TABLE foo (int bar);
sqlite> .exit

如果使用API,则需要在调用打开函数之前注册VFS:

sqlite3_vfs_register(sqlite3_vfs_find("unix-excl"), 1);
sqlite3_open("foo.db", &db);

如果使用PHP PDO,那么你就卡住了,除非你愿意重新编译pdo_sqlite PHP扩展。

好消息,原来在EFS上运行sqlite是可能的。 - Jan
可能性是存在的,但通常这仍然是一个不好的想法:https://www.sqlite.org/howtocorrupt.html - 2tim

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