使用Room构建的数据库文件始终为4KiB的问题排查
问题分析与解决
嘿,你遇到的这个情况其实不是代码有问题,而是Room默认使用的WAL(Write-Ahead Logging)日志模式导致的正常现象,我来给你拆解一下:
为什么主数据库文件只有4KiB且表为空?
Room从1.0版本开始就默认启用了WAL模式,这种模式下:
- 所有写入操作不会直接写入
nodes_database.db主文件,而是先写入nodes_database.db-wal这个预写日志文件; nodes_database.db-shm是WAL模式用到的共享内存文件,用来协调数据库的读写操作;- 主db文件只保留了数据库的初始结构(空表、元数据等),所以大小只有4KiB,直接用普通SQLite工具打开会看不到数据。
为什么Stetho能查到完整内容?
Stetho在连接数据库查询时,会自动识别WAL模式并处理相关的日志文件,它会把-wal里的未合并数据和主db文件的内容整合起来返回,所以你能看到完整的插入数据。
如果需要让数据写入主db文件(比如要拷贝文件查看),可以这么做:
方法1:关闭数据库时自动合并
当你调用RoomDatabase.close()关闭数据库实例时,Room会自动触发WAL日志的合并操作,把-wal里的内容写入主db文件,之后主db文件就能看到完整数据了。方法2:强制触发合并操作
可以在需要的时候手动调用SQLite的检查点方法,强制合并日志到主db:// 获取可写数据库并执行完整检查点 INSTANCE.openHelper.getWritableDatabase().walCheckpoint(SQLiteDatabase.CHECKPOINT_FULL);方法3:关闭WAL模式(不推荐)
如果不需要WAL的性能优势,可以在构建数据库时切换回传统的TRUNCATE模式,但这会牺牲并发读写能力和写入性能:INSTANCE = Room.databaseBuilder(context.getApplicationContext(), NodesRoomDatabase.class, "nodes_database.db") .setJournalMode(RoomDatabase.JournalMode.TRUNCATE) .build();
小提示
WAL模式是Room官方推荐的默认配置,它比传统模式有更好的性能和并发支持,所以除非你有必须直接操作主db文件的场景,否则建议保持默认模式哦。
内容的提问来源于stack exchange,提问作者Alex Liu
相关产品推荐
相关产品推荐

