Sqlite3 回滚日志文件及其生命周期
文章目录
- Sqlite3 回滚日志文件及其生命周期
- 1. joural文件的作用
- 2.joural文件的生命周期
- 3.如何避免joural文件频繁创建和删除
- 4 总结
1. joural文件的作用
Sqlite3 的日志文件以后缀 joural 命名。
joural文件即日志文件,或称为回滚日志文件。像SQLite这样的事务数据库的一个重要功能就是“原子提交”,在提交的过程中,如果发生操作系统崩溃或断电等意外情况,在下次开机时,我们希望数据库能回滚到提交前的状态,以此来保证数据的“完整性”。
为了能够实现回滚功能,SQLite在对数据文件进行任何更改之前,SQLite先创建一个回滚日志文件,该文件包含将数据库还原到原始状态所需的所有信息,并在提交成功首删除回滚文件。
如果发生意外情况,下一次首次连接时,SQLite先会检查是否存在joural文件,如果存在则自动根据joural文件回滚。
2.joural文件的生命周期
默认情况下,joural文件在一次提交中被创建,在提交完成后生命结束。下图显示了SQLite数据库的一次提交过程。
3.如何避免joural文件频繁创建和删除
我们知道在很多系统上,删除文件是个消耗大量I/O资源的操作,并且很多的闪存设备写入次数是有限制,如果每一次提交时都创建删除日志文件,这将极大降低闪存设备寿命。因此我们不希望SQLite频繁的创建和删除joural文件,可喜的是这一项操作是可配置的,例如:
PRAGMA journal_mode = DELETE;
日志文件设置为可删除的,并在提交事务后被删除。
PRAGMA journal_mode = PERSIST;
“永久日志模式”不会删除日志文件,而是通过将标头清零达到使文件失效的目的。
永久日志模式的使用在许多系统上提供了显着的性能改进。当然,缺点是在事务提交后很长时间,日志文件仍会使用磁盘空间并保留在磁盘上。删除持久日志文件的唯一安全方法是在日志记录模式设置为DELETE的情况下提交事务
显然只更新标头,只需要很少的写操作,这将延长闪存设备的寿命,这对嵌入式系统而言是很重要的。
PRAGMA journal_mode = TRUNCATE;
在截断日志模式下,通过将日志文件截短为零而不是删除日志文件(如在DELETE模式下)或将标头清零(如在PERSIST模式下)来提交事务。TRUNCATE模式具有PERSIST模式的优点,即无需更新包含日志文件和数据库的目录。因此,截断文件通常比删除文件快。TRUNCATE的另一个优点是,它不会跟随系统调用(例如:fsync())将更改同步到磁盘。这样做可能会更安全。但是在许多现代文件系统上,截断是原子和同步操作,因此我们认为,面对电源故障,TRUNCATE通常将是安全的。
在具有同步文件系统的嵌入式系统上,TRUNCATE导致的行为比PERSIST慢。提交操作的速度相同,但是在TRUNCATE之后进行后续事务处理的速度较慢,因为覆盖现有内容要比追加到文件末尾要快。新的日记文件条目将始终在TRUNCATE之后追加,但通常会被PERSIST覆盖。
4 总结
Sqlite3 的日志文件可被设置为三种模式:DELETE 、 PERSIST、TRUNCATE。
从效率而言,其效率由高到低是:PERSIST > TRUNCATE > DELETE