笔记
btree模块,通过pager模块来读和写二进制文件,通过pager模块,把sqlite文件看成一个由page组成的数组。所有的操作,都是先从磁盘读取到内存,操做完了以后再写回。
这里假设 数据库足够大,比内存还要大
再内存中用来存放部分数据库数据的叫做cache 或者 data buffer 在sqlite中称作为page cahce
pager的责任是使得上层透明,并且提供一个在 mian memory中可以通过地址访问的功能
pager的功能
也提供一些事务处理的特性:事务管理,数据管理,日志管理,锁管理
- 数据管理:协调,cache和文件数据读写,文件空间管理
- 日志管理:journal file when wrting
- 锁管理:使得事务成为可能
pager实现数据持久化,和事务自动化
每个pagecache 表示一个一个程序的内存空间,多个连接,有多个pagecache。
sqlite 没有使用系统的缓存机制自己每次需要cache的时候直接从native file 获取
旧版本是这样,我阅读的新的版本,在开启debug模式的时候,才会直接从硬盘读取
pager manage至关重要
pager 结构中的ahash数组,是用来存放hashtable用来访问在 page cache中的page(新版本,中page结构没有ahash这个数组,而是存放一个函数的指针,通过传入xGet函数指针,传入参数访问,真正获取的函数为getPageNormal)
每个hash,指向一个桶,每个桶,中有多个page,组成一个linkedlist 内部是无序的
pgHdr只能pager看到 btree不能看到
dirty表示,还没有写回到native文件中
nref来运行LRU
nref表明是否pined down 如果没有pined down 就是free的 后面用来作替换算法时使用的
读写都遵循LRU算法 sqlite 用queue来 管理 free pages(unpind page)
page 如何从file到memory
在pager结构中,有pager->fd->pMethods->xRead 方法,通过调用,seekAndRead,从磁盘读取到内存
开启了debug模式,会直接从磁盘中读取文件,而不会使用cache
从已知的头中设置一些信息?
在分配内存方面大多使用memcpy为什么?以及区别
strcpy 和 memcpy 主要有以下 3 方面的区别。
1、复制的内容不同。strcpy 只能复制字符串,而 memcpy 可以复制任意内容,例如字符数组、整型、结构体、类等。
2、复制的方法不同。strcpy 不需要指定长度,它遇到被复制字符的串结束符 "\0" 才结束,所以容易溢出。memcpy 则是根据其第 3 个参数决定复制的长度。
3、用途不同。通常在复制字符串时用 strcpy,而需要复制其他类型数据时则一般用 memcpy
新版本3.16.2,替代ahash为xget函数指针来获取page
每个PCache对应db的中的一个page
btree层,只操作,database pages 的复制层
btree通过page number从pager处 获得 page的内存可访问地址
再修改之前,btree 会通知 pager从而让page 及时保存
当btree 修改完成后也会通知page 从而page及时保存 每个pager对象,只关联一个文件
pager 只有一个,当有多个线程链接的时候,会创建多个pager cahce提供使用
PgHdr 每个再cache中的page又这个结构管理
btree getpage,通常情况通过getPageNormal
方法,从cache中获取page
从磁盘读入指定内存方法
开启debug编译选项
sqltie提供统一的接口
sqlite3OsRead(pPager->fd, pDest, N, 0);
读入特定长度内容底层调用unixread方法
使用memcpy调用