【问题标题】:disk I/O error with SQLiteSQLite 的磁盘 I/O 错误
【发布时间】:2018-11-13 07:12:22
【问题描述】:

我有一个(小)动态网站,它(大致)是一个使用 SQLite 数据库的 Perl CGI 脚本。 Package DBI 是 Perl 中使用的抽象层。

大约一周前,我开始看到这个错误信息:

dbdimp.c 第 271 行的磁盘 I/O 错误 (10)

由于这是一个运行 Apache 的托管站点,我无法查看硬盘是否(几乎)已满。对命令“df”的访问被禁用....但我使用(UNIX)shell 命令“yes > blah”来测试磁盘仍然可以创建新文件。我的数据库非常小——不到 50 KB。

我检查了文件和目录权限:目录和所有父级都是 a+r,a+x(全部 + 读/可执行)。包含我的 SQLite 数据库文件的目录也是 a+w(全部 + 写入)。数据库文件本身有a+w,a+r(全部+读/写)。

我编写了一个简单的 Perl 程序来测试我可以运行失败的选择查询:它运行良好。

我在数据库上运行了查询“VACUUM”。我再次尝试了测试 - 没有任何改善。

我将 SQLite 数据库转储为原始 SQL(使用 SQLite shell 命令“.dump”)并重建。我再次尝试了测试 - 没有任何改善。

有什么建议吗?我很困惑...通常,上面的列表可以捕获大多数编程/设置错误。

【问题讨论】:

标签: perl sqlite cgi dbi


【解决方案1】:

另一个原因:

  • 数据库文件可写
  • 数据库日志文件(以 -journal 结尾)不可可写

当数据库文件不可写时,您会收到“只读数据库”错误。当它是可写的,但日志文件不是时,你会得到“I/O 错误”。

【讨论】:

    【解决方案2】:

    不幸的是,sqlite3.h 对具体问题的描述不是很清楚。错误代码 10 在这里定义:

    #define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */
    

    您可能会遇到 /tmp 在某些点已满或 sqlite 无法访问内存以写入其页面缓存的问题。如果您的数据库为 50kb,这不太可能,因为 sqlite 应该能够将您的页面缓存保存在内存中。

    您可以尝试制作数据库的副本,希望 sqlite 可以读取复制的数据库并更新您的代码以反映这一点:

    $sqlite3 your.db
    sqlite> begin immediate;
    <press CTRL+Z>
    $cp your.db copyofyour.db
    $exit
    sqlite> rollback;
    

    您还应该检查日志以查看是每个请求都发生这种情况还是间歇性发生这种情况。您可能想查看是否可以访问其他命令来监控服务器运行状况(顶部,免费)。能够重现该问题似乎是您手头的首要任务。如果您无法始终如一地重现它,则可能是内存相关问题。

    【讨论】:

    • 好建议!很酷的想法。我会记下未来的问题。不幸的是,在这种情况下——这是由于 FreeBSD 内核错误(正如 NearlyFreeSpeech.net 的支持论坛所解释的那样)。
    • 您能多谈谈这个错误吗?我想我可能会遇到类似的事情......
    • @ChrisVandevelde:抱歉,NFS.net 管理员没有提供有关 FreeBSD SQLite 错误的更多详细信息。不过,我的问题已经解决了。
    【解决方案3】:

    如果文件锁定失败,则可能的错误来源可能是难以检测的。您可以测试您的文件系统当前是否支持文件锁定

    flock testfile touch testfile
    

    例如,NFS 文件系统可能会根据 NFS 服务器配置表现出这种行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多