SQLite3 - 单个数据库文件原子提交的实现

SQLite 是支持事务的。
原子提交:当个事务中的对数据库的修改要么全做要么都不做。 这一特性保证数据库的一致性。

假设
(1)操作系统更新磁盘的最小单位是扇区。
(2)SQLite并不假定扇区写操作是原子的。SQLite3.5新增了一个VFS(虚拟文件系统)接口,SQLite通过VFS与实际的文件系统进行交互。 xDeviceCharacteristics:VFS的一个常用函数。
(3) 扇区写操作是线性的。(线性:当开始扇区写操作时,硬件从前一个扇区的结束点开始,然后一字节一字节的写入,直到此扇区的结束点)
(4)SQLite假定操作系统会对写进行缓冲,SQLite需要在关键点做"flush" 或 "fsync" 函数调用

*************************************************************
1. 单个数据库文件中的提交
步骤如下:
(1) 获得共享锁。
SQLITE在更新数据库之前要先读数据库,所以要先获得共享锁。
SQLite的共享锁是针对操作系统缓存的,而非磁盘文件,进程消失或系统崩溃都会导致锁丢失。

(2) 读取数据
从磁盘读到操作系统缓存,再读到用户进程。

(3) 申请一个保留锁(Reserved Lock)
保留锁的作用是告诉数据库我要修改数据库了,其他事务不能获得保留锁。所以一个数据库只能有一个保留锁。保留锁可以和其他共享锁共存,都可以读取数据库。

(4)生成回滚日志文件(Rollback Journals log file)
将修改前的数据写到回滚日志文件中

(5)修改用户进程空间中的数据

(6)将回滚日志文件写到磁盘

(7) 获得独享锁, 修改数据库磁盘文件
获得独享锁是分两步完成的,先获得一个“临界锁”, 然后升级成独享锁。
临界锁的作用是防止生成新的共享锁。

(8) 将修改更新到磁盘
先更新到操作系统缓存, 然后调用flush或sync写到磁盘文件中。

(9)删除回滚日志文件

(10) 释放锁,事务结束


***********************************************************************

2. 如果发生错误,回滚
如果在上面(8)之前发生了错误, 就需要回滚。
当发生故障恢复访问后, 进程访问数据库要求获得共享锁时,会先检查是否有"hot journal"。 hot journal表示之前有事务发生错误,需要回滚。
判断hot journal的条件(所有都要满足)
(1) 有回滚日志文件存在
(2) 回滚日志文件非空文件
(3) 数据库上没有保留锁
(4) 回滚日志文件的文件头是正确的,非零
(5) 回滚日志文件不包含master journal file的文件名, 如果有,master journal file要存在

如果以上条件都满足,则开始回滚
(1) 获得独享锁
(2) 读取回滚日志文件中的内存,更新数据库文件
(3) 删除日志文件
(4) 独享锁变成共享锁,结束回滚,继续进程的访问作业

参考
http://www.sqlite.org/atomiccommit.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值