oceanbase存储引擎1
Diskmanager 数据库管理磁盘上的文件的模块 也叫存储引擎
1.一般来说数据库的数据都是存硬盘上的 但用户要操作的话 需要加载到内存里去
存储引擎就是管理这 个来回流动的过程
2.存储是分层的 越往上层越小越贵越快 如图
上层的虽然易失 但可以随机访问 可以按字节获取地址 下层那些硬盘之类的是顺序访问 且只能一块一块
3.好的存储引擎允许用户管理一个巨大的数据库 不让数据库经常读写磁盘(因为慢) 持续读写比随机读写入快
4.大多数数据库都面向硬盘(用户的东西最后归于硬盘文件) 面向内存的不考虑硬盘 更快但更小
5.内存上有个buffer pool 缓冲池 有一定的大小 硬盘上的文件的第一页的块读到缓冲池中(像一个loading的过程)
6.还有一个execution engine 执行器部分 执行器想获取一个东西 缓冲池先把文件目录读进去再解析 找到第n页地址加载进去 此时数据已在内存 便提供给执行器
7.mmap提供虚拟内存 和实际硬盘一样大 想找page1 操作系统直接把page1弄到物理内存里 再将虚拟内存与其链接 无需自己管理内存加载卸载 但是如果物理内存满了 操作系统不知道该卸哪一个 会陷入卡顿
8.为什么DBMS基本优于OS
a.改动数据时 需自己控制保存时间 OS控制性能差
b.预先取出数据 执行器无需等待从磁盘到内存的过程
c.自己管理新老数据的替换
d.数据库可能多线程 线程的优先级需要自己控制
两个大问题
数据库的数据落在什么文件?
数据库如何管理数据在磁盘 内存间的流动?
第一个问题:
数据库存文件就是直接存在磁盘里 OS不关心存的是什么
存储引擎/存储管理器:维护管理操作系统中的数据文件
1.有些自己去管理时间空间上如何存储文件
2.将文件按编码切好了 是一个个小页
页(page) 一般512B-16KB
数据库文件太大了 所以切成一个个小数据块
1.可能存数据 表结构 索引 日志等等
2.大部分数据库每个页的功能是固定的 该存什么不会存其它的
3.每个页有个id
堆文件(database heap)
一堆无序的页 里面存了很多数据(可能是随机数据)
页需要有增删改查功能(能增加)
如果只有一个堆文件 执行器要第x页 每个页一样大小所以很好查找 如果有多个则需要其它手段看在哪个堆文件
堆文件的第一个页(header) 里面有两个链表 一个链接空页(free page list) 一个链接有数据的(data page list )
目录文件 page directory 链接各个page 也是靠链接
每个页也有一个头(page header) 头里是关于内容的 存大小 存个checksum(校验码) 数据库版本 并发(有没有被锁 被隐藏) 压缩的信息等
任何page中的数据(data)的存储有两个流派
1.最常用的 slotted pages 意思是除了header和data 还有一个slot array存每个数据在哪 这样文件顺序可以乱 但是好找
2.只存数据 数据碎片化(有些可能破坏了依赖顺序)
record ids
全局需要寻找数据或者记录 需要一个id号 一般是page_id+slot/offset
这个是数据库内部用的 外部软件不能用
数据(tuple)
在磁盘上的表现是一组二进制字节 如果不拿数据库解析就是一堆乱码
DBMS就是将他们编码好之后放磁盘上
tuple也有header 是元数据 里面首先有与上文类似的info 还有记录NULL 因为tuple没有分隔符 个个紧挨
tuple的data不存表结构 一般是顺序存储
也有一种存的不是数据(log - structured file) 存的是数据的变化 拿数据是从新往旧回放 找到其最开始的起始点 再往后找到最新的变化
如果是之前的方式 需要找到对应页 再找到对应数据进行修改 这种方式只需要新建一个页 往里记日志完事
页内很多信息可以压缩成一条 比如压缩后:
id =1,val =a
id =2,val=b
DELETE id=4
并且还有level0文件合并以后压缩成level1文件的操作 比如文件1有数据a的插入操作 文件2有数据a的修改操作 可以合并压缩
这种一般用在kv数据库 因为只有一个键一个值 直接就更新成最新值
这就是rocksDB的基本原理
也有些压缩方式是合并以后没有层的概念 这样插入的时候可以把随机写变成顺序写