SQLite数据库文件格式(十五)

本文档描述和定义磁盘上的数据库文件 自 SQLite 以来所有版本使用的格式 版本 3.0.0 (2004-06-18).

1. 数据库文件

SQLite数据库的完整状态通常是 包含在磁盘上的单个文件中,称为“主数据库文件”。

在事务期间,SQLite存储其他信息 在称为“回滚日志”的第二个文件中,或者如果 SQLite 处于 WAL 模式,则为预写日志文件。

1.1. 热门期刊

如果应用程序或 主机在事务完成之前崩溃,然后回滚 日志或预写日志包含所需的信息 将主数据库文件还原到一致状态。回滚时 日志或预写日志包含恢复所需的信息 数据库的状态,它们被称为“热日志”或“热WAL文件”。 热日志和WAL文件只是错误恢复过程中的一个因素 场景等并不常见,但它们是 SQLite 状态的一部分 数据库等不能忽视。本文档定义了格式 回滚日志和预写日志文件,但重点是 在主数据库文件上。

1.2. 页面

主数据库文件由一个或多个页面组成。的大小 Page 是介于 512 和 65536 之间的 2 次幂(含)。内所有页面 相同的数据库具有相同的大小。数据库文件的页面大小 由位于 从数据库文件开头开始的 16 个字节。

页码以 1 开头。最大页码为 4294967294(2,32-2)。最小尺寸 SQLite 数据库是一个 512 字节的页面。 最大大小的数据库将是 4294967294 页,每 65536 字节 页面或 281,474,976,579,584 字节(约 281 TB)。通常 SQLite 会 达到底层文件系统或磁盘的最大文件大小限制 硬件早在它达到自己的内部大小限制之前。

在通常的使用中,SQLite数据库的大小往往从几千字节不等 到几千兆字节,尽管已知存在 TB 大小的 SQLite 数据库 在生产中。

在任何时间点,主数据库中的每个页面都有一个 使用以下方法之一:

  • 锁定字节页面
  • 自由列表页面
    • 自由列表主干页面
    • 自由列表叶页面
  • b 树页面
    • 表格b-tree内页
    • 表 b 树叶页
    • 索引 b 树内页
    • 索引 b 树叶页
  • 有效负载溢出页面
  • 指针映射页

对主数据库文件的所有读取和写入都从一页开始 boundary 和 all writes 的大小为整数页数。读 通常也是整数页的大小,但有一个例外 当数据库首次打开时,前 100 个字节的 数据库文件(数据库文件头)作为子页面大小单位读取。

在修改数据库的任何信息页面之前, 该页面的原始未修改内容将写入 回滚日志。如果事务中断并且需要 回滚,然后可以使用回滚日志来恢复 数据库恢复到其原始状态。Freelist 叶子页没有 需要在回滚时还原的信息,因此它们 在修改之前没有写入期刊,以便 减少磁盘 I/O。

1.3. 数据库头

数据库文件的前 100 个字节构成数据库文件 页眉。数据库文件头分为多个字段,如下所示 下表。数据库文件头中的所有多字节字段都是 首先使用最高有效字节 (big-endian) 存储。

数据库头格式

偏移 大小 说明
0 16 标头字符串:“SQLite 格式 3\000”
16 2 数据库页面大小(以字节为单位)。必须是 2 之间的 512 次幂 和 32768(含 32768),或值 1 表示页面大小为 65536。
18 1 文件格式写入版本。1 用于遗产;2 表示 WAL
19 1 文件格式读取版本。1 用于遗产;2 表示 WAL
20 1 每页末尾未使用的“保留”空间的字节数。通常为 0。
21 1 最大嵌入有效载荷分数。必须年满 64 岁。
22 1 最小嵌入式有效载荷分数。必须年满 32 岁。
23 1 叶片有效载荷分数。必须年满 32 岁。
24 4 文件更改计数器。
28 4 数据库文件的大小(以页为单位)。“in-header 数据库大小”。
32 4 第一个自由列表主干页面的页码。
36 4 免费列表页面总数。
40 4 架构 cookie。
44 4 架构格式编号。支持的架构格式为 1、2、3 和 4。
48 4 默认页面缓存大小。
52 4 自动抽真空或 增量真空模式,否则为零。
56 4 数据库文本编码。值为 1 表示 UTF-8。值为 2 表示 UTF-16le。值 3 表示 UTF-16be。
60 4 user_version编译指示读取和设置的“用户版本”。
64 4 增量真空模式为 True(非零)。否则为 false(零)。
68 4 PRAGMA 设置的“应用程序 ID”application_id。
72 20 保留用于扩展。必须为零。
92 4 version-valid-for 编号
96 4 SQLITE_VERSION_NUMBER

1.3.1. 魔术头字符串

每个有效的 SQLite 数据库文件都以下列 16 个字节开头 (十六进制):53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00。此字节序列 对应于 UTF-8 字符串“SQLite format 3”,包括 nul 末尾的终结者角色。

1.3.2. 页面大小

从偏移量 16 开始的双字节值决定了 数据库。对于 SQLite 版本 3.7.0.1 (2010-08-04) 在更早的时候,这个值是 解释为大端整数,并且必须是 2 之间的幂 512 和 32768(含)。从 SQLite 版本 3.7.1 (2010-08-23) 开始,一个页面 支持 65536 字节的大小。值 65536 不适合 双字节整数,因此要指定 65536 字节的页面大小,值 偏移量为 16 0x00 0x01。 此值可以解释为大端 1 并被认为是一个表示 65536 页面大小的幻数。 或者可以将两字节字段视为一个小字节数,然后说 它表示页面大小除以 256。这两个 对 page-size 字段的解释是等效的。

1.3.3. 文件格式版本号

偏移的文件格式写入版本和文件格式读取版本 18 和 19 旨在允许增强文件格式 在 SQLite 的未来版本中。在当前版本的 SQLite 中,两者都 对于回滚日记模式,这些值为 1,对于 WAL 日记模式,这些值为 2。如果 SQLite 的版本编码为当前 文件格式规范遇到一个数据库文件,其中读取 version 为 1 或 2,但写入版本大于 2,则数据库 文件必须被视为只读。如果具有读取版本的数据库文件 如果遇到大于 2,则无法读取或写入该数据库。

1.3.4. 每页保留字节数

SQLite能够在 每个页面的末尾,供扩展使用。这些额外的字节是 例如,SQLite 加密扩展用于存储随机数 和/或与每个页面关联的加密校验和。这 偏移量 20 处的 1 字节整数中的“保留空间”大小是数字 每页末尾的字节空间,以保留扩展名。 此值通常为 0。该值可能是奇数。

数据库页的“可用大小”是 标头中偏移量 16 处的 2 字节整数减去“保留”空间大小 记录在标头偏移量 20 处的 1 字节整数中。可用 页面大小可能是奇数。但是,可用尺寸不是 允许小于 480。换句话说,如果页面大小为 512, 则预留空间大小不能超过 32。

1.3.5. 有效载荷分数

最大和最小嵌入有效载荷分数和叶片 有效负载分数值必须为 64、32 和 32。这些值是 最初打算成为可用于 修改 B 树算法的存储格式。但是,那 不支持功能,并且当前没有要添加的计划 未来的支持。因此,这三个字节固定在 指定的值。

1.3.6. 文件更改计数器

文件更改计数器是一个 4 字节的大端整数,位于 每当数据库文件解锁时递增的偏移量 24 修改后。 当两个或多个进程读取同一个数据库文件时,每个进程 进程可以通过监视来检测来自其他进程的数据库更改 找零钱计数器。 在以下情况下,进程通常希望刷新其数据库页缓存 另一个进程修改了数据库,因为缓存已过时。 文件更改计数器便于执行此操作。

在 WAL 模式下,使用 wal-index 检测对数据库的更改 因此不需要找零计数器。因此,更改计数器可能 在 WAL 模式下,每个事务都不会递增。

1.3.7. Header 数据库大小

偏移量为 28 处的 4 字节大端整数进入标头 以页为单位存储数据库文件的大小。如果此 in-header datasize size 无效(见下一段),则数据库 大小是通过查看来计算的 以数据库文件的实际大小。SQLite 的旧版本 忽略头数据库大小,使用实际文件大小 惟独。较新版本的 SQLite 使用 in-header 数据库 size(如果可用),但回退到实际文件大小,如果 In-Header 数据库大小无效。

仅当以下情况时,才认为标头内数据库大小有效 它不为零,如果 4 字节更改计数器在偏移量 24 处 与偏移量 92 处的 4 字节 version-valid-for 数字完全匹配。 标头内数据库大小始终有效 当仅使用最新版本的 SQLite 修改数据库时, 版本 3.7.0 (2010-07-21) 及更高版本。 如果旧版本的SQLite写入数据库,则不会 知道更新 In-Header 数据库大小,因此 In-Header 数据库大小可能不正确。但是SQLite的旧版本 还将保持偏移量 92 处的 version-valid-for 编号不变 所以它不会与更改计数器匹配。因此,无效的 in-header 可以通过观察何时来检测(并忽略)数据库大小 更改计数器与 version-valid-for 编号不匹配。

1.3.8. 免费页面列表

数据库文件中未使用的页面存储在自由列表上。这 偏移量 32 处的 4 字节大端整数存储 自由列表的第一页,如果自由列表为空,则为零。 偏移量 36 处的 4 字节大端整数存储总计 自由列表上的页数。

架构 cookie 是一个偏移量为 40 的 4 字节大端整数 每当数据库架构发生更改时,该值都会递增。一个 准备好的语句是针对特定版本的 数据库架构。当数据库架构发生更改时,语句 必须重新准备。当准备好的语句运行时,它首先检查 架构 cookie,以确保值与语句时的值相同 已准备,如果架构 cookie 已更改,则语句 自动重新准备并重新运行,否则会因SQLITE_SCHEMA错误而中止。

1.3.10. 模式格式编号

架构格式编号是偏移量为 44 处的 4 字节大端整数。 架构格式编号类似于文件格式读取和写入 偏移量 18 和 19 处的版本号,但架构格式号除外 指高级 SQL 格式,而不是低级 b 树 格式。目前定义了四个架构格式编号:

  1. 格式 1 被所有版本的 SQLite 理解到版本 3.0.0 (2004-06-18)。
  2. 格式 2 添加了同一表中行的功能 具有不同数量的列,以支持 ALTER TABLE ...ADD COLUMN 功能。支持 读写格式 2 在 2005-02-20 的 SQLite 版本 3.1.3 中添加了。
  3. 格式 3 添加了 ALTER TABLE 添加的额外列的功能...ADD COLUMN 设置为非 NULL 默认值 值。此功能是在 2005-03-11 的 SQLite 版本 3.1.4 中添加的。
  4. 格式 4 导致 SQLite 遵循 DESC 关键字 on 索引声明。(DESC 关键字在索引中被忽略 格式 1、2 和 3。 格式 4 还添加了两个新的布尔记录类型值(序列号类型 8 和 9)。在 SQLite 3.3.0 中添加了对格式 4 的支持 2006-01-10.

默认情况下,SQLite 创建的新数据库文件使用格式 4。 legacy_file_format编译指示可用于导致 SQLite 使用格式 1 创建新的数据库文件。 格式版本号可以通过以下方式默认为 1 而不是 4 在编译时设置 SQLITE_DEFAULT_FILE_FORMAT=1。

1.3.11. 建议的缓存大小

偏移量为 48 处的 4 字节大端有符号整数是建议的 数据库文件的缓存大小(以页为单位)。该值是一个建议 只有,SQLite没有义务履行它。绝对值 的整数用作建议的大小。建议的缓存大小 可以使用default_cache_size Pragma 进行设置。

1.3.12. 增量真空设置

使用偏移量 52 和 64 处的两个 4 字节大端整数 管理auto_vacuumincremental_vacuum模式。如果 偏移量 52 处的整数为零,则指针映射 (PTRMAP) 页面为 从数据库文件中省略,既不auto_vacuum也不 支持incremental_vacuum。如果偏移量 52 处的整数为 非零,则它是 数据库文件,数据库文件将包含 ptrmap 页面,并且 mode 必须是 auto_vacuum 或 incremental_vacuum。在后者中 情况下,偏移量 64 处的整数对于 incremental_vacuum 和 auto_vacuum为 false。如果偏移量 52 处的整数为零,则 偏移量 64 处的整数也必须为零。

1.3.13. 文本编码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

界忆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值