这是我参与「第五届青训营」伴学笔记创作活动的第23天
发展历史
数据库发展最初过程中,诞生过3种数据模型,最终关系型模型成为了应用最为广泛的数据库模型
网状模型:用有向图表示实体和实体之间的联系的数据结构模型称为网状数据模型层次模型:层次数据模型是用树状<层次>结构来组织数据的数据模型关系模型:使用表格表示实体和实体之间关系的数据模型称之为关系数据模型
关键技术
SQL执行流程
在SQL执行过程中,需要经历SQL引擎、存储引擎、以及事务引擎等模块。而其中SQL引擎又分为Parser、Optimizer、Executor几个部分:
SQL引擎
解析器
Paser:经过词法分析、语法分析生成语法树,然后对语法树进行合法性校验
优化器
Optimizer:根据Parser产生的语法树,根据规则或者代价产生执行计划树
基于规则的优化RBO
条件化简表连接优化:总是小表先进行连接Scan优化:唯一索引、普通索引、全表扫描
基于代价的优化器CBO
- 什么是代价:
时间、IO、CPU、NET、MEM - 不仅是单个查询的代价最低,而是
整体查询的代价最低
执行器
Executor:根据计划树进行执行,常见的执行方式是火山模型
火山模型
- 每个
Operator(算子)调用Next操作,访问下层的Operator,获得下层Operator返回的一行数据,经过计算之后,将这行数据返回给上层 优点:每个算子是独立抽象实现,相互之间没有耦合,逻辑结构简单缺点:每计算一条数据有多次的函数开销,导致CPU效率不高
向量化模型
- 每个Operatot每次操作计算的数据不再是一行数据,而是
一批数据,计算完成之后向上层算子返回一个Batch - 优点:
- 函数调用次数为1/N
- CPU cache命中率更高
- 可以利用CPU提供的
SIMD机制:在一条CPU指令里边可以计算多条数据
编译执行
- 将所有的操作封装到一个函数里面,函调用的代价也能大幅度降低
- 使用LLVM动态编译技术:动态生成执行的代码路径
存储引擎
内存池
Buffer Pool:用于缓存数据,减少磁盘IO的开销
- 每个
页16K,每个chunk128M - 以
128M为单位向系统申请内存 - 再将其分为一个个页,每个页用于存储数据
- 将每个buffer pool分为多个instance,以
降低页面访问的冲突
管理数据的方式:
Hash Map:根据page ID计算,以找到对应的内存block
改良的LRU算法:最近最长使用的数据保留下来,其余数据从内存中淘汰
页
Page:数据存储的最基本单位,一般为16KB
变长字段列表:哪些字段是变长的,分别是多长NULL标志位:哪些数据是空的,哪些是有数据的Header:delete _mask:表示词条数据是否被删除next_recoder:下一条数据位置recoder_type:表示当前记录的类型
row_id:数据的ID信息,递增trx_id:事务ID的信息,递增roll_ptr:指向undo数据Coln:一个个数据
B+树索引
- 页目录中先使用二分查找定位到对应的槽
- 然后再遍历该槽对应分组中的记录
事务引擎
原子性
- Atomicity:InnoDB中通过undo日志实现了数据库的原子性,通过
Undo Log,数据库可以回滚到事务开始的状态 - Undo Log是逻辑日志,记录的是数据的增量变化,并利用Undo Log可以进行事务回滚,保证事务的原子性
隔离性
- Isolation:通过
Undo Log实现MVCC(多版本并发控制),降低读写冲突 - 通过锁机制来实现
- MVCC的意义:
- 读写互补阻塞
- 降低死锁概率
- 实现一致性读
- Undo Log在MVCC的作用:
- 每个事务有单增的事务ID
- 数据页的行记录中包含了
DB_ROW_ID、DB_RTX_ID、DB_ROLL_PTR DB_ROLL_PTR将数据行的所有快照都通过链表的结构串联起来
持久性
Durability:通过Redo Log(一种WAL实现方式)来保证事务在提交后一定能持久化到磁盘中
- 如何保证事务结束后对数据的永久保存
事务提交前页面写盘(×),原因:随机IO问题:数据在磁盘中大多是分开存储的,增加随机访问负载写放大问题:对数据最小的管理单元是页,本身只需要小小修改数据,结果写了整个页,导致写放大
Redo Log(√),原理:- Redo Log是物理日志,记录页面的变化,
保证事务的持久化 - 如果
数据写入磁盘前发生故障,重启MySQL后会根据redo log重做
- Redo Log是物理日志,记录页面的变化,
一致性
Consistency:一致性本质上是一种业务层的限制