You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

指定/tmp/a为SQLite数据库路径时,删除文件后仍出现I/O错误求助

问题描述

当将SQLite数据库指定在/tmp/a路径下运行测试时,出现两类错误:

  • SQLITE_IOERR_DELETE_NOENT (5898)
  • SQLITE_READONLY_DBMOVED (1032)

删除/tmp/a文件后错误仍持续,但切换到/tmp/b路径时所有操作完全正常。

关键细节:

  • 错误发生在数据库初始化完成之后(已成功创建所有表,说明初始写入操作可行)
  • 两个文件的权限完全一致:
$ ls -ahlv /tmp/a
-rw-r--r-- 1 rik users 24K Jan 15 18:00 /tmp/a

$ ls -ahlv /tmp/b
-rw-r--r-- 1 rik users 24K Jan 15 18:00 /tmp/b

个人怀疑问题与SSD缓存有关,后续会跟进更新,现寻求解决方案。

可能的解决方案

1. 排查/tmp文件系统的异常特性

/tmp通常是tmpfs内存文件系统,可能存在inode复用、路径别名或自动清理机制:

  • 用stat对比两个文件的inode、设备ID等元信息,确认是否存在差异:
    stat /tmp/a /tmp/b
    
  • 检查是否存在指向/tmp/a的软/硬链接,或系统是否有定时清理/tmp的服务(如systemd-tmpfiles)

2. 清理残留的文件句柄

即使删除了/tmp/a,如果测试进程仍持有该文件的句柄,SQLite会因无法定位原文件触发SQLITE_READONLY_DBMOVED:

  • 用lsof查找持有/tmp/a句柄的进程:
    lsof | grep /tmp/a
    
  • 彻底重启测试进程,确保没有残留的文件引用

3. 调整SQLite配置参数

针对SSD缓存的猜测,可通过调整SQLite参数减少缓存依赖:

  • 限制缓存大小,避免过度依赖文件系统缓存:
    PRAGMA cache_size = -1024; -- 设置为1MB内存缓存
    
  • 切换日志模式为DELETE,减少额外临时文件的生成:
    PRAGMA journal_mode = DELETE;
    

4. 排除/tmp路径的特殊性

将数据库迁移到非/tmp路径(如~/test_a)测试,确认是否是/tmp文件系统本身的问题:

  • 创建测试路径并赋予权限:
    mkdir -p ~/test_db && chmod 755 ~/test_db
    
  • 将数据库指定到该路径运行测试,观察错误是否重现

内容的提问来源于stack exchange,提问作者RikH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 04:00:52