2021SC@SDUSC SQLite源码分析(一)————SQLite内核结构与功能分析

一、内核概述

为了能更好的理解 SQLite,我们先从总的结构上讨论了内核,从全局把握 SQLite 很重要。SQLite 的内核实现不是很难,但是也不是很简单。本次主要讨论虚拟机 (Virtual Machine)。

VDBE 是 SQLite 的核心,它的上层模块和下层模块都是本质上都是为它服务的。它的实现位于 vbde.c, vdbe.h, vdbeapi.c, vdbeInt.h, 和 vdbemem.c 几个文件中。

它通过底层的基础设施 B+Tree 执行由编译器(Compiler)生成的字节代码,这种字节代码程序语言(bytecode programming lauguage)是为了进行查询,读取和修改数据库而专门设计的。字节代码在内存中被封装成 sqlite3_stmt 对象(内部叫做 Vdbe,见 vdbeInt.h),Vdbe(或者说 statement)包含执行程序所需要的一切:
a) a bytecode program
b) names and data types for all result columns
c) values bound to input parameters
d) a program counter
e) an execution stack of operands
f) an arbitrary amount of “numbered” memory cells
g) other run-time state information (such as open BTree objects, sorters, lists, sets)

字节代码和汇编程序十分类似,每一条指令由操作码和三个操作数构成:<opcode, P1, P2, P3>。
Opcode为一定功能的操作码,为了理解,可以看成一个函数。
P1 是 32 位的有符号整数,
p2 是 31 位的无符号整数,它通常是导致跳转(jump)的指令的目标地址(destination),当然这了有其它用途;
p3 为一个以 null 结尾的字符串或者其它结构体的指针。和 C API 不同的是,VDBE 操作码经常变化,所以不应该用字节码写程序。
下面的几个 C API 直接和 VDBE 交互:
• sqlite3_bind_xxx() functions
• sqlite3_step()
• sqlite3_reset()
• sqlite3_column_xxx() functions
• sqlite3_finalize()

二、VDBE与B-tree的关系

B-Tree 使得 VDBE 可以在 O(logN)下查询,插入和删除数据,以及 O(1)下双向遍历结果集。B-Tree 不会直接读写磁盘,它仅仅维护着页面(pages)之间的关系。

当 B-TREE 需要页面或者修改页面时,它就会调用Pager。当修改页面时,pager 保证原始页面首先写入日志文件,当它完成写操作时,pager 根据事务状态决定如何做。B-tree 不直接读写文件,而是通过 page cache 这个缓冲模块读写文件对于性能是有重要意义的,这和操作系统读写文件类似,在 Linux 中,操作系统的上层模块并不直接调用设备驱动读写设备,而是通过一个高速缓冲模块调用设备驱动读写文件,并将结果存到高速缓冲区。

三、B-tree初步分析

SQLite中每个数据库完全存储在单个磁盘文件中,因为B树进行数据的查找、删除、添加速度快,所以这些数据以B树数据结构的形式存储在磁盘上(实现代码在btree.c源文件中)。

B树的典型结构如图2所示。B+树是应文件系统所需而出的一种B-树的变型树。B+树可以进行两种查找算法,第一种,从最小关键字起顺序查找;第二种,从根结点开始,进行随机查找。B-tree应用到数据库的每个表和索引中。所有B-tree存储在相同的磁盘文件中。

Alt
(图源网络)

btreeInt.h 中 b树结构定义:

struct Btree {
  sqlite3 *db;       /* The database connection holding this btree */
  BtShared *pBt;     /* Sharable content of this btree */
  u8 inTrans;        /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
  u8 sharable;       /* True if we can share pBt with another db */
  u8 locked;         /* True if db currently has pBt locked */
  u8 hasIncrblobCur; /* True if there are one or more Incrblob cursors */
  int wantToLock;    /* Number of nested calls to sqlite3BtreeEnter() */
  int nBackup;       /* Number of backup operations reading this btree */
  u32 iBDataVersion; /* Combines with pBt->pPager->iDataVersion */
  Btree *pNext;      /* List of other sharable Btrees from the same db */
  Btree *pPrev;      /* Back pointer of the same list */
#ifdef SQLITE_DEBUG
  u64 nSeek;         /* Calls to sqlite3BtreeMovetoUnpacked() */
#endif
#ifndef SQLITE_OMIT_SHARED_CACHE
  BtLock lock;       /* Object used to lock page 1 */
#endif
};

功能分析

参考文献:《Inside SQLite》

B-tree为SQLiteVDBE提供O(logN)级时间复杂度的查询和插入,通过遍历记录实现O(1)级时间复杂度的删除。B-tree是自平衡的,并能够对碎片清理和内存再分配进行自动管理。B-tree对如何读写磁盘没有限定,只是关注页之间的关系。
B-tree的职责就是排序,它维护着多个页之间错综复杂的关系,这些关系能够保证快速定位并找到一切有联系的数据。B-tree将页面组织成树状结构,这些组织结构很适合搜索,页面就是树的叶子。Pager帮助B-tree管理页面,它负责传输。
B-tree是为查询而高度优化了的。它使用特殊的算法来预测将来要使用哪些页,从而让B-tree保存该页面以便尽可能快地工作。
数据库中所有的页都是以1开始顺序编号的。一个数据库是由多个B-tree组成的——每张表以及每个索引各对应一个B-tree。数据库中每张表或索引都以根页面作为第一页。所有的索引和表的根页面都存储在sqlite_master表中。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值