标签:
atomic commit
)。也就是在一个事务中进行的对数据库的写操作要么全部执行,要么全部不执行。看起来像是对数据库不同部分的写操作时瞬时发生的。rollback mode
。如果数据库在WAL mode下运行,策略和这篇文章不同。xDeviceCharacteristics
。这个函数和文件系统交互,并提供文件系统的一些特性,比如扇区写操作是否是原子的。如果这个扇区写操作时原子的,那么SQLite会利用这些特性。然而Unix和Windows缺省的xDeviceCharacteristics
函数不会提供这些信息。flush
或fsync
操作。SQLite假设这个操作在数据被写入文件之前不会返回。fluse
或fsync
操作不是这样子的。这样子,在commit的过程中发生掉电,会导致数据库文件损坏。xDeviceCharacteristics
方法确定在改变文件大小之前,数据已经被写入到文件中,那么SQLite会利用这个特性。然而默认的实现没有确认这个特性。单个文件commit过程
初始状态
中间部分是系统的磁盘缓冲区。
?
获取读锁
在写操作之前需要获取读锁,获取数据库的基本数据,这样子才能解析SQL语句。
注意共享锁只针对系统的磁盘缓存,而不是磁盘文件。文件锁其实就是系统内核的一些flag。在系统crash或掉电之后,锁会失效。通常创建锁的进程退出也会导致锁失效。
?
从数据库中读数据
先读到系统磁盘缓存,再读到用户空间。如果命中了缓存,那么会直接从磁盘缓存中读到用户空间。
注意不是把整个数据库读入内存。
?
获取reserved lock
在对数据库进行改变之前,要先获取reserved lock。允许其他拥有共享读锁的进程操作,但是一个数据库文件只能有要给reserved lock。保证了只有同时最多一个进程可以进行数据库写操作。
?
创建回滚日志文件
日志文件就是要改变的数据库文件中原有的page。
此外还包括一个头部,记录了原有数据库文件的大小。page的number被写入到了每一个数据库的page中。
注意此时并没有写文件到磁盘中。
?
在用户空间改变数据库的page
每一个数据库链接都有自己的数据库文件拷贝。所以,此时其他数据库连接仍然可以正常进行读操作。
?
把日志文件刷入磁盘中
在大多数系统中,需要进行两次flush或fsync操作。第一次将文件数据刷入文件中,第二次用来更改header中的记录日志文件的page数目,并把header刷入文件。
?
获取exclusive锁
获取exclusive锁分两步。首先获取一个pending锁,保证不会有新的写操作和读操作。然后等待其他的读进程结束,释放读锁,最后获取exclusive锁。
?
将用户空间中的数据写入数据库文件
此时可以确定没有其他数据库连接在从数据库中读文件。这一步通常只会写入到磁盘缓存中,不会写到数据库文件。
?
将更改写入磁盘文件中
调用fsync或flush操作。这一部和写日志文件到磁盘中占用了一个transaction中最多的时间。
?
删除日志文件
SQLite gives the appearance of having made no changes to the database file or having made the complete set of changes to the database file depending on whether or not the rollback journal file exists.
删除日志文件不是原子的,但是从用户看来,这个操作是原子的。询问操作系统这个文件是否存在,回答是yes或no。
在一些系统中,删除文件时一个耗时的操作。SQLite可以配置为将文件的大小改为0或用0来覆盖日志文件的头部。在这两种情况下,日志文件都不可能进行恢复,因此SQLite认为commit已经完成。
?
释放锁
在这张图里,用户空间的数据库内容已经被清空。在最新版本中,做了优化。在数据库第一个page中,维护了一个计数器,每一次写操作,都会对这个计数器加一。如果计数器不变,这个数据库连接就可以重复利用用户空间中的数据库内容。
?
回滚
由于一个commit操作需要时间。在这个过程中,如果发生了crash或掉电,就需要进行回滚以保证数据库事务的完成是『瞬时』的。利用数据库日志文件回滚到这个数据库事务发生之前。
多文件提交
commit过程的重要细节
优化
性能分析表示SQLite将大多数时间花费在了磁盘IO。因此如果可以减少磁盘IO的话,就可以提升SQLite的性能。下面介绍一些SQLite采用的在保证事务原子性的前提下提升性能的一些方法。
PRAGMA journal_mode=PERSIST;
PRAGMA journal_mode=TRUNCATE;
测试提交行为原子性
导致数据库损坏的可能性
总结及未来的路
标签:
原文地址:http://www.cnblogs.com/huahuahu/p/sqlite-yuan-zi-ti-jiao-yuan-li.html