工作原理
默认情况下,sqlite通过回滚日志来实现事物的原子性提交(atomic commit and rollback
),但是在3.7以后的版本中,sqlite支持WAL模式,其实现方法和回滚日志正好相反。
回滚日志是将原先的数据库相关信息保存在回滚日志中,在commit的时候将回滚日志删除,如果在这之前发生错误,数据库将会按照既定程序(https://sqlite.org/lockingv3.html)回滚到回滚日志所记录的状态。
WAL模式是不改变原有数据库,将更新信息存到WAL文件中,当达到一定条件(默认为1000页,编译阶段可设置)时才写入原始数据库。因为写入时不会修改原始的数据库,所以写入操作和读取操作可以同时执行
检查点
正常模式下的数据库有两种状态:读和写。而WAL模式下的数据库有三种状态:读、写、检查点。
检查点用于将WAL文件中的所有的更新同步到原始数据库中,默认为1000页,编译时期可以通过SQLITE_DEFAULT_WAL_AUTOCHECKPOINT参数来设置,应用也可以关闭自动检查点来手动同步数据。
并发
当一个读事物开始时,首先会在WAL文件中获取到一个最后一次有效提交的标志,称之为end mark。因为WAL文件会不断增大,不同的读事件很可能会持有不同的end mark。但是在读事物这个过程中,end mark不会改变,以此来保证读事物只会读取某个时间节点上的数据库信息。
获取到end mark后,读事物会去检查WAL文件,如果在WAL文件中存在需要读取的内容页,则会先拉取WAL文件中的数据(这个过程是WRITE?还是check?还是只是单纯的READ WAL FILE?),如果没有则直接读取原始数据库。
wal-index在共享缓存中使用,以此来确保读事物快速读取文件并最小程度的进行文件I/O操作。因为WAL的前提是共享缓存模式,这就意味着所有的读操作必须在同一个机器中进行,所以WAL模式不能在网络模式中使用。
写操作仅仅只是在WAL文件尾部附加修改。因为只有一个WAL文件,所以同一时间只能有一个写事物。
网友评论