加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

sqlite 更新数据后重启被还原的问题

发布时间:2020-12-12 19:29:34 所属栏目:百科 来源:网络整理
导读:最近调查一个问题,用sqlite3 记录一条item,显示成功后机器直接断电重启发现数据没有变化。 明明操作已经显示success了,为什么数据没有写进去呢? 对数据库基本是小白,一直是做底层开发的,上面的兄弟说sqlite操作数据库,fsync或者fdatasync后,数据没有

最近调查一个问题,用sqlite3 记录一条item,显示成功后机器直接断电重启发现数据没有变化。
明明操作已经显示success了,为什么数据没有写进去呢?

对数据库基本是小白,一直是做底层开发的,上面的兄弟说sqlite操作数据库,fsync或者fdatasync后,数据没有写到磁盘导致了这个问题。 好吧,调查fsync fdatasync,系统调用最后都是一个fsync,datasync做参数0或者1,更新的元数据时候做了判断区分,这兄弟两可都是货真价实的同步调用啊。代码上分析直接写入了这个fd的file map data和inode信息,真正写入后才返回啊。

问题来了,数据库fdatasync内容莫非真的没有写进去,只能看sqlite数据库怎么调用的。发现里面只是加读写锁机制。啊哟我勒个去,莫非是锁干的坏事,写没成功,debug一把,调用的顺序就是这么的正常,毫无破绽。加了各种log,打开了内核的block dump log看哪些文件写了。发现很奇怪,数据库文件确实已经被写了,那为啥写完断电重启后数据文件又被还原了呢。

strace跟踪了一下,发现在数据库更新时,会去创建一个 -journal的日志文件,写完后会unlink掉这个日志文件。去查了一个官方文档,这-journal文件就是为了对应 crash和 突然power off的情况的。这下知道原因了,原来都是这个 -journal 文件搞的鬼。 unlink后 在kernel 调度IO刷新操作之前掉电,那么这个-journal文件其实没有被真正删除,还是存在于磁盘上的。

下次操作数据库时,sqlite检查到有 -journal文件,认为上次是异常处理,从-journal文件中将更新的内容还原回来了。还是原来的数据,还是熟习的配方。 这个数据库就是这么设计的,没有问题,数据库需要满足ACID (Atomicity,Consistency,Isolation,Durability)特性,用日志来防止上次的异常操作。sqlite叫做hot journal

原因清楚了,为什么会出现这样的情况呢,为什么不像数据库写一样,写了数据后用fdatasync来保证数据写了磁盘上。猜测了一下,unlink文件没有类似 fsync和fdatasync 一样同步的操作可以确保文件从磁盘上删除的。删除动作,只能操作sync去更新整个文件系统,估计这样做的话性能就要降低了。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读