深入理解RDBMS| 青训营笔记

101 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第19天。

发展历程

DBMS数据模型

网状模型

多对多的关系,子节点可以有多个父节点。

image.png

优势

  • 能直接描述现实世界
  • 存储效率高

劣势:

  • 结构复杂
  • 用户不易使用
  • 访问程序设计复杂

层次模型

使用树形结构来描述实体及其之间的关系的数据模型。

image.png

优势

  • 结构简单
  • 查询效率高
  • 可以提供较好的的完整性支持

劣势

  • 无法表示M:N的关系
  • 插入、删除限制多
  • 遍历子节点必须经过父节点
  • 访问程序设计复杂

关系模型

所有的数据都是一张二维表。

image.png

优势

实体及实体间的联系都通过二维表结构表示 可以方便的表示M:N的关系 数据访问路径对用户透明

劣势

关系查询效率不够高 关系必须规范化

SQL语言

将Codd关系数据库的12条准则的数学定义以简单的关键字语法表现出来,里程碑式的提出了SQL(Structured Query Language)语言。

优点

  • 语法风格接近自然语言
  • 高度非过程化
  • 面向集合的操作方式
  • 语言简洁,易学易用

image.png

历史概览

image.png

关键技术

一条SQL的一生

image.png 终端 -> Router -> RDBMS -> Parser(语法解析器) -> Optimizer(优化器) -> Executor -> Data File

  • AST: 语法树
  • Plan: 也是一种树状结构

SQL引擎

解析器(Parser)

一般分为词法分析(Lexical analysis)、语法分析(Syntax analysis)、语义分析(Semantic analyzer)等步骤。

词法分析

  • 关键字:UPDATE/SET/WHERE
  • 表列名: account_table/balance/name
  • 常量: '小目标' / '抖音'
  • 运算符: '=' / '-'
  • 结束符: ';'

语法分析(生成一个语法树):

 struct UpdateStmt {
    Table: account_table;
    Fields: balance;
    Values: balance - '小目标';
    Where: name = '抖音';
    OrderBy: null;
    Limit: null;
 }

语义分析(合法性分析)

  • 检查account_table是否存在
  • 检查balance/name是否存在
  • 场景常量的数据类型是否合法

优化器(Optimizer)

image.png

基于规则的优化(RBO Rule Base Optimizer)

  • 条件化简
  • 表连接优化
    • 总是小表先进行连接
  • Scan优化
    • 唯一索引
    • 普通索引
    • 全表扫描

基于代价的优化(CBO Cost Base Optimizer)

  • 代价是诸如 时间、I/O、CPU、NET、MEM等
  • 但基于用户体验比较重要的是时间

执行器(Executor)

火山模型

image.png 每个Operator(算子)调用Next操作,访问下层Operator,获得下层Operator返回的一行数据,经过计算之后,将这行数据返回给上层。

  • 优点
    • 每个算子独立抽象实现,相互之间没有耦合,逻辑结构简单
  • 缺点
    • 每计算一条函数有多次函数调用开销,导致CPU效率不高
优化方式:向量化

每个Operator每次操作计算的不再是一行数据,而是一批数据(Batch N行数据),计算完成后向上层算子返回一个Batch。

image.png

  • 优点
    • 函数调用次数降低为1/N
    • CPU cache命中率更高
    • 可以利用CPU提供的SIMD(Single Instruction Multi Data)机制
优化方式:编译执行

将所有的操作封装到一个函数里,函数调用的代价也能大幅降低。

image.png 实现方法是使用LLVM动态编译执行技术。

存储引擎

InnoDB(MySQL中)

image.png

In-Memory(内存部分)

做内存缓冲。

  • Buffer Pool(缓冲池)
  • Change Buffer
  • Adaptive Hash Index
  • Log Buffer(I/O会写到这上面然后再写到磁盘上)

On-Disk(磁盘部分)

  • System Tablespace(ibdata1)
    • 存储元信息:表名、列名、用户权限等
  • General Tablespaces(xxx.ibd)
    • 存储普通字段
  • Undo Tablespaces(xxx.ibu)
  • Temporary Tablespaces(xxx.ibt)
  • Redo Log(ib_logfileN)

Buffer pool

  • 每个页面(Page)是16K大小,是对数据管理的最小单元
  • 每个chunk是128M向系统申请内存

image.png 通过HashMap快速找到block。

image.png

  • LRU算法
    • 把最近最常使用的数据保留下来,淘汰不常使用的数据,达到释放内存的目的

Page

image.png

  • delete_mask: 标识此条数据是否被删除
  • next_round: 下一条数据的位置
  • record_type: 标识当前记录的类型

B+ tree

B+树作为索引,是二分查找树(B树)的扩展。

image.png

  • 在一个页面内:
    • 页目录中使用二分法快速定位到对应的槽,然后再遍历该槽对应分组中的记录即可快速找到指定的记录
  • 从根到叶:
    • 中间节点存储

事务引擎

Atomicity 与 Undo Log

如何将数据库回退到修改之前的状态?

通过Undo Log实现。

  • Undo Log是逻辑日志,记录的是数据的增量变化,利用Undo Log可以进行事务回滚,从而保证事务的原子性。
  • 同时也实现了多版本并发控制(MVCC),解决读写冲突和一致性读的问题

image.png

Isolation 与 锁

  • 同时读的时候加Share Lock
  • 同时写的时候加Exclusive Lock
  • 同时读写的时候MVCC

Isolation 与 MVCC

MVCC的意义

  • 读写互不阻塞
  • 降低死锁概率
  • 实现一致性读

image.png
老版本的数据记录在Undo里(自下而上版本越高),新数据记录在数据页里,通过roll pointer来逐渐形成链表。

Undo Log在MVCC的作用
  • 每个事务有一个单增的事务ID
  • 数据页的行记录包含了DB_ROW_ID,DB_TRX_ID,DB_ROLL_PTR
  • DB_ROLL_PTR将数据行的所有快照记录都通过链表的结构串联了起来

Durability 与 Redo Log

如何保证事务结束后,对数据的修改永久的保存?
  • 事务提交前页面写盘
    • 问题:随机I/O、写放大
  • WAL(Write-ahead-logging)
    • redo log是物理日志,记录的是页面的变化,它的作用是保证事务持久化,如果数据写入磁盘前发生故障,重启Mysql后会根据redo log重做

以上内容若有不正之处,恳请您不吝指正!