最近调查一个问题,用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去更新整个文件系统,估计这样做的话性能就要降低了。
sqlite 更新数据后重启被还原的问题 最近调查一个问题,用sqlite3 记录一条item,显示成功后机器直接断电重启发现数据没有变化。 明明操作已经显示success了,为什么数据没有写进去呢?
原文
SQLite
Expert Professional 打开加密
数据
库
(已修改)
版本:
sqlite
expert professional 4.2.0.739(x86)
目的:用
SQLite
Expert打开本地已加密的
数据
库(已知加密密码)
什么叫
数据
,什么叫做
数据
库?
数据
:能够输入计算机并能被计算机程序识别和处理的信息集合
数据
库:
数据
库是在
数据
库管理系统管理和控制之下,存放在存储介质上的
数据
集合
Sqlite
数据
库是轻量级的,源码c,代码大小250KB,2TB大小。
windows用法
1、在路径位置的地方输入
sqlite
3.exe可以直接进入命令行终端,很方便
当然也可以设置环境变量的方式,使它在哪个路径都可以找到并且运行
sqlite
3.exe
(1)此电脑->属性->高级系统设置
(2)第四步是把
sqlite
.exe所在
情景:最近在使用JPA持久层框架,碰到
数据
库清空的
问题
,发现
重启
项目后,
数据
库中的
数据
会被自动清空。
解决方法:将spring.jpa.hibernate.ddl-auto属性设为update。
ddl-auto:create----每次运行该程序,没有表格会新建表格,表内有
数据
会清空。
ddl-auto:create-drop----每次程序结束的时候会清空表。
ddl-auto...
Write-Ahead Logging
1. 概述
SQLite
实现原子提交和回滚的默认方法是rollback journal。从3.7.0版本开始,可以使用Write-Ahead Log(简称WAL)。
WAL模式的优点:
在大多数场景明显更快;
读写操作可并发;
顺序访问磁盘;
使用fsync()操作更少,因此在调用fsync()中断的系统上更不容易发生
问题
;
WAL模式的缺点:
WAL模式通常要求VFS支持共享内存(例外情况见: WAL without shared mem