SQLite的原子提交--多文件场景

5. Multi-file Commit

SQLite数据库通过使用 ATTACH DATABASE命令,允许在一个数据库连接中同时操作2个或者多个数据库文件.d当在一个事务中修改多个数据库文件时,所有这些数据库文件将进行原子提交.也就是说,这些数据库文件要么全部被更新,要么全部不更新.在多个数据库文件上进行原子提交要比在一个数据库文件上进行原子提交要复杂.这一部将描述SQLite数据如何在多个数据库文件上进行原子提交.

5.1. Separate Rollback Journals For Each Database

当在一个事务操作中涉及到多个数据库文件时,每个数据库文件有其自己的回滚日志文件,并且每个数据库文件是彼此独立的被锁定的.下图显示了在一个事务中,修改了3个不同的数据库文件的场景.此时的情况和步骤3.6中的单文件事务场景是类似的.每个数据库文件有一个预订锁(reserved lock).对于每个数据库文件,更新之前的原始内容已经写入到了其回滚日志文件中,但是, 回滚日志文件还没有被刷新到磁盘,因此数据库文件还没有发生改变,数据的更新只存在于用户缓存中.

这一部分的示意图在之前单文件提交的基础上做了一些简化.蓝色仍然代表原始内容数据,粉红色仍然代表更新的内容.但是,在数据库文件和回滚日志文件中,将不再显示单独的页面,并且我们将不再区分操作系统缓存中的信息和磁盘上的信息.所有这些要素在多文件提交场景中仍然适用,并没有引入任何新的信息,只不过徒增了示意图的空间,因此,这些要素将不再显示.
在这里插入图片描述

5.2. The Master Journal File

在多文件提交中,下一步,将创建一个主日志文件(master journal).主日志文件的名称是原始数据库文件名称加上后缀-mjHHHHHHHH后成的.其中,HHHHHHHH是一个随机的32位的16进制数,每次创建猪日志文件时,这个随机数后缀都会改变.另外,原始的数据库文件指的是用 sqlite3_open()打开的数据库文件,而不是ATTACHed命令附着的辅助数据库文件.

需要注意的是,上面段落中给定的计算主日志文件名称的公式对应SQLite3.5.0的执行,这个计算公式并不属于SQLite数据库的规范,并且将来有可能改变.

与回滚日志文件不同的是,主日志文件不包含任何原始数据库文件的内容.主日志文件包含事务操作中,每个数据库文件对应的回滚日志文件的路径名称.

主日志文件一经创建,在执行任何其他操作之前,其内容就会被刷新到磁盘.在Unix操作系统上,包含主日志文件的目录也会被刷新到磁盘,以确保在断电故障以后,主日志文件仍然存在该目录下.

主日志文件的作用就是确保在断电故障时,事务中的多文件提交是原子的.但是,如果数据库文件有其他设置(比如PRAGMA synchronous=OFF 或者 PRAGMA journal_mode=MEMORY), 这些设置允许在断电故障时,对数据完整性有所妥协,那么,作为一种优化手段,此时可以不创建主日志文件.
在这里插入图片描述

5.3. Updating Rollback Journal Headers

接下来,在每个回滚日志文件头中记录主日志文件的绝对路径名称.回滚日志文件在创建的时候,会在头部预留空间来保存主日志文件名称.

在将主日志文件名称写入回滚日志头部之前和之后,都需要将回滚日志文件刷新到磁盘,进行2次刷新是非常重要的.幸运的是, 第二次的刷新操作因为通常情况下只需写入一个页面(第一个页面),所以写入操作并不昂贵.

这个步骤和单文件提交的步骤3.7是类似的.
在这里插入图片描述

5.4. Updating The Database Files

一旦所有的回滚日志文件刷新到磁盘,更新数据库文件就是安全的.在写入这些更新之前, 我们必须获得所有数据库文件的排他所(exclusive lock).在所有的更新操作之后,刷新这些更新到磁盘,以免断电故障或者操作系统崩溃导致数据丢失.

这个步骤对应之前单文件提交中的3.8,3.9和3.10.
在这里插入图片描述

5.5. Delete The Master Journal File

接下来是删除主日志文件.这是多文件提交中的关键点.这个步骤对应单文件提交3.11中的回滚日志文件删除步骤.

如果这时候发生断电故障或者操作系统崩溃,系统重新上电以后,事务不会回滚,即使回滚日志文件存在.区别在于,回滚日志文件头中存在主日志文件信息.重启以后,SQLite判断回滚日志文件需要回滚的依据是要么回滚日志文件头中没有主日志文件信息(单文件提交的情况也是如此),要么主日志文件存在于磁盘上.
在这里插入图片描述

5.6. Clean Up The Rollback Journals

多文件提交的最后一步是删除各个回滚日志文件,并且释放数据库文件上的排他锁(exclusive locks),以便其他进程可以看到数据库文件的改变.这个步骤对应单文件提交的3.12.

这时,事务已经提交,因此删除回滚日志文件的顺序并不是很关键了.当前的执行是删除一个回滚日志文件并释放其对应的数据库文件锁,然后再操作下一个回滚日志文件.但是,将来这个逻辑可能改变,就是说先删除所有的回滚日志文件,然后释放他们对应的数据库文件上的锁.只要在数据库文件锁被释放之前,其回滚日志文件被删除,那么就不会有问题.
在这里插入图片描述


原文链接:https://www.sqlite.org/atomiccommit.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值