【问题标题】:SQLite disk I/O error with large DB file大型数据库文件的 SQLite 磁盘 I/O 错误
【发布时间】:2018-03-25 22:27:39
【问题描述】:

在我的 C# 程序中,我正在读取大约 350GB 的压缩 CSV 文件并将数据存储在 SQLite v3 数据库中。我正在使用来自 NuGet 的System.Data.SQLite

我的数据库目前大约 147GB,在尝试运行下一个 INSERT 查询时出现错误:

(778) os_win.c:41557: (665) winWrite2(D:\System.db) - 由于文件系统限制,请求的操作无法完成。
错误:第 1 行附近:磁盘 I/O 错误。”

驱动器为 1.81TiB,可用空间为 1.37TiB。卷是 NTFS。数据库是 146650432KiB。 ChkDsk 报告一切正常,驱动器正常工作。

我的程序和 DB Browser 应用程序中的任何 INSERT 都会发生这种情况。

(如果我运行 VACUUM 操作,数据库可能会大幅缩小,因为我运行了很多 INSERT 语句)

我估计 12 个表中大约有 35 亿行。根据我的阅读,这种大小的 SQLite 数据库应该没有问题。

任何想法为什么会发生这种情况以及如何解决它?理想情况下,如果我不必从头开始整个导入过程,那就太好了,因为这需要几天时间才能完成,仅完成了大约 20%。

【问题讨论】:

  • 这是 32 位系统还是 64 位系统?实际过程也有同样的问题?
  • 64 位系统。该应用程序针对“任何 CPU”进行编译,并且该进程是 32 位的。我已经重新构建为 64 位,让我们看看它是如何运行的。
  • 进程为64位时仍然会发生。
  • 我发现一旦我在单个表中获得超过 8GB 的​​空间,SQLite 就没有我需要的必要性能。我会寻找一个不同的数据库。还有stackoverflow.com/questions/784173/…
  • @Kevin 太好了,我会记住这一点,但它并不能真正回答问题。

标签: sqlite


【解决方案1】:

Windows 错误代码 665 与消息中的内容完全相同:文件系统已达到某个限制。

限制不是文件大小本身,而是管理碎片文件所需的内部结构的数量。 (完全相同的问题happens with Microsoft's own SQL Server。)

Microsoft 有一个hot fix,它允许您使用为这些结构保留更多空间的文件系统重新格式化驱动器。 但现在解决此问题的更简单方法是运行碎片整理程序,或者只制作文件的新副本(如果您有足够的可用空间)。

如果可能,尽量避免文件碎片化,即在填充数据库时不要将其他数据写入同一文件系统。 或者,为了避免更小的碎片,通过临时插入一个大行来大量扩展数据库文件的大小:

CREATE TABLE t(x);
INSERT INTO t VALUES(zeroblob(500*1024*1024));  -- 500 MB
DROP TABLE t;

【讨论】:

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