【问题标题】:Parsing SQLite Database Schema in sqlitedb file?在 sqlitedb 文件中解析 SQLite 数据库模式?
【发布时间】:2014-03-23 02:11:41
【问题描述】:

我编写了一个解析 SQLite 文件的程序,我可以解析来自 b-tree 页面的所有数据以记录、列和值,但我需要解析表的架构,我发现类似于存储在第 1 页中的 数据库架构(根页面) 我可以用Hex Editor 看到它,我发现sqlite_master 的结构,我完全按照http://sqlite.org/fileformat2.html 中的说明阅读它

我想知道如何在 db 文件中找到 sqlite_master 表的第一个字节,如何检测架构的起始字节? SQLite DB Header 中有什么相关的吗?

编辑 1(更多信息):

例如: 我用十六进制编辑器打开了 sqlite db,(如果你检查我的页面大小是 4096 字节并且我在图像中标记了页眉):

我标记了以 05 开头的根页眉表示 the page is an interior table b-tree page,请检查 B-tree 页眉格式 (http://sqlite.org/fileformat2.html) 并且它有 5 个单元格,您可以在此单元格中看到它指针数组:0FFB、0FF6、0FF1、0FEC、0FE7(在结束标头之后开始)并且所有单元格都有 5 个字节并从 0FE7 开始,然后您可以在图片中看到的模式(在文本部分)从 232~240 开始,并且我在不同的地方检查其他数据库和架构...

编辑 2:

您可以从https://www.dropbox.com/s/lanky02kneyb74w/31bb7ba8914766d4ba40d6dfb6113c8b614be442下载示例文件

编辑 3:

在我的文件中你可以看到

$ hexdump -C 31bb7ba8914766d4ba40d6dfb6113c8b614be442

00000000  53 51 4c 69 74 65 20 66  6f 72 6d 61 74 20 33 00  |SQLite format 3.|
00000010  10 00 02 02 00 40 20 20  00 00 00 02 00 00 00 3f  |.....@  .......?|
00000020  00 00 00 00 00 00 00 00  00 00 00 47 00 00 00 04  |...........G....|
00000030  00 00 00 00 00 00 00 00  00 00 00 01 00 00 00 00  |................|
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 02  |................|
00000060  00 2d e2 25 05 00 00 00  05 0f e7 00 00 00 00 3d  |.-.%...........=|
00000070  0f fb 0f f6 0f f1 0f ec  0f e7 08 7f 07 9d 08 3c  |...............<|
00000080  07 01 06 22 05 92 04 fe  03 fc 04 c1 03 4d 02 b8  |...".........M..|
00000090  02 0a 02 75 01 32 01 c7  00 e9 00 e9 00 00 00 00  |...u.2..........|
000000a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000000e0  00 00 00 00 00 00 00 00  00 47 18 06 17 5b 35 01  |.........G...[5.|
000000f0  00 69 6e 64 65 78 73 71  6c 69 74 65 5f 61 75 74  |.indexsqlite_aut|
00000100  6f 69 6e 64 65 78 5f 41  42 4d 75 6c 74 69 56 61  |oindex_ABMultiVa|
00000110  6c 75 65 45 6e 74 72 79  4b 65 79 5f 31 41 42 4d  |lueEntryKey_1ABM|
00000120  75 6c 74 69 56 61 6c 75  65 45 6e 74 72 79 4b 65  |ultiValueEntryKe|

Page Header ( offset 64)

05          <- interior table b-tree page
0000        <- Byte offset into the page of the first freeblock
0005        <- Number of cells on this page
0FE7        <- Offset to the first byte of the cell content area
00          <- Number of fragmented free bytes
0000003D    (61) <- The right-most pointer

Cell Array Pointers & Cell Contents:
(Table Interior Cell Format)

Cell Pointer| Page number of left child | Rowid
------------|---------------------------|-------
0FFB        | 0000001A      (26)        | 15
0FF6        | 0000001C      (28)        | 2D
0FF1        | 00000031      (49)        | 3C
0FEC        | 00000039      (57)        | 48
0FE7        | 0000003C      (60)        | 4C     <- equal to (Offset to the first byte of the cell content area) in page header

【问题讨论】:

  • 您对该文件有什么具体问题?
  • @CL。 tanx 这么多花花公子试图解决我的 prb,如果你还记得我,你跟着我写 SQLite 解析器来提取数据和恢复已删除的记录 (stackoverflow.com/questions/21628240/…),我写了它,它的工作正常并提取所有值,但现在,我只是想加载表的架构,我怎么能找到架构?,如果你阅读第 1 页标题或单元格指针数组(根页),你可以t find offset of schema, and cant 加载 sqlite_master 表..
  • @CL.,如果第一个表像我的文件一样是interior table b-tree page,请告诉我如何在 sqlite db 文件中找到架构偏移量......!?
  • 更新了答案。架构存储在sqlite_master 表的sql 列中。

标签: sqlite parsing


【解决方案1】:

我知道您的问题是在一年前提出的,您可能已经解决了,但我想提交一个答案,以防其他人有同样的问题。我和你的情况一样,迈赫迪。我想读取一个 SQLite 数据库文件,并且正在寻找主表/模式。它似乎在第 1 页,但标题没有指向它。我的困惑有两个原因。

(1) 我的 SQLite 数据库文件中有很多“死”数据没有被使用。我相信随着数据库的创建和增长,实际活动数据的位置会移动,并且旧位置不会被零覆盖。搜索一些“CREATE TABLE”语句在文件的不同位置发现了多个结果。后来我确定实际模式被拆分并位于第 18、10 和 8 页(第 1 页内部表指向)。如果不是原因 #2,我会更早发现这一点。

(2) 我算错了页码的字节位置,搞糊涂了。其中 p = page #,s = page size,我以为是 [p * s] .... 但实际上是 [(p-1) * s] (除了从字节 100 开始的第 1 页)。换句话说,我认为页码从 0 开始,而不是 1。

作为补充说明,我认为http://sqlite.org/fileformat2.html 页面缺少一些重要信息。具体来说,它没有解释“根页面”编号在模式表中的位置(它在字段 4 中)。我在 sqlite.org 页面上找不到此信息。

【讨论】:

  • 我不知道这个答案是否正确,但无论哪种方式都很好。 :)
【解决方案2】:

您链接到的文档在section 2.6 中说:

数据库文件的第 1 页是表 b-tree 的根页面,其中包含一个名为“sqlite_master”的特殊表

section 1.5:

一个 b-tree 页面按以下顺序划分为多个区域:

  1. 100 字节的数据库文件头(仅在第 1 页找到)
  2. 8 或 12 字节的 b-tree 页头……

例如,对于这个数据库:

$ sqlite3 test.db "创建表 hello(world);"
$ hexdump -C test.db
00000000 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 |SQLite 格式 3.|
00000010 04 00 01 01 00 40 20 20 00 00 00 01 00 00 00 02 |.....@ ........|
00000020 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 |......|
00000030 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 |......|
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |......|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 |......|
00000060 00 2d e6 03 0d 00 00 00 01 03 cf 00 03 cf 00 00 |.-æ........Ï..Ï..|
00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |......|
*
000003c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2f |................/|
000003d0 01 06 17 17 17 01 3f 74 61 62 6c 65 68 65 6c 6c |......?
000003e0 6f 68 65 6c 6c 6f 02 43 52 45 41 54 45 20 54 41 |ohello.CREATE TA|
000003f0 42 4c 45 20 68 65 6c 6c 6f 28 77 6f 72 6c 64 29 |BLE 你好(世界)|
00000400 0d 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00 |......|
00000410 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |......|

...偏移量 0x64 处的页眉具有以下值:

  • 0d: page 是叶子表 b-tree 页面
  • 0000: 空闲块偏移量
  • 0001: 单元格数
  • 03cf: 单元格内容的偏移量
  • 00:碎片化的空闲字节
  • 03cf: 第一个单元格指针

在偏移量3cf 处,您有一个标准的表b-tree 叶单元格,包含sqlite_master 表的唯一行:

sqlite> select * from sqlite_master;
类型名称 tbl_name 根页 sql
---------- ---------- ---------- ---------- ---------- ---------------
表你好你好 2 创建表你好(世界)

【讨论】:

  • tanx 帮助我,我读过它,但在页眉中你找不到任何关于模式和单元指针数组的东西对我没有帮助.. 模式放置在未分配区域.. 请检查编辑 1,再次坦克
  • 我放弃了投票,但请检查我的数据库文件,它以内部表 b 树页面开头.. 请检查它(它是 iphone 的联系人数据库,您可以使用 SQLite 管理器打开它)。 .dropbox.com/s/lanky02kneyb74w/…
  • 请检查链接并帮助我了解这个文件...从内部 b-tree 页面开始。
  • tanx cl 但请在我的文件示例或任何以 b-tree 表内部开头的 sqlite db 中显示我......请告诉我当根页面是 b-tree 内部时如何找到架构偏移量桌子..? & tanx 寻求帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-05
  • 2022-06-10
  • 2022-10-09
  • 1970-01-01
  • 2018-08-11
  • 2011-08-06
相关资源
最近更新 更多