数据库事务的ACID特性:
原子性(Atomicity):【一个事务必须都发生或都不发生(基于日志的Undo log机制)】
事务是一个不可再分割的工作单元,一个事务中的操作要么都发生,要么都不发生。
一致性(Consistency):【终极目标】
数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。
隔离性(Solation):【并发的事务之间不影响(脏读、幻读和不可重复读)(加锁)(MVCC也借助了Undo log)】
多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。
持久性(Durability):【保证数据不会因宕机等故障而消失(Redo log)】
在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
在转账的例子中,A-100,B+100,如果只是A-100,B的账户没有变,这时认为同时违反了原子性和一致性
在事务处理的ACID属性中,一致性是最基本的属性,其它的三个属性都为了保证一致性而存在的。
关键技术
一条SQL的一生;SQL引擎;存储引擎;事务引擎
一条SQL的一生
SQL引擎:
- Parser查询解析:SQL 语言接近自然语言,入门容易。 但是各种关键字、操作符组合起来, 可以表达丰富的语意。因此想要处理SQL命令, 首先将文本解析成结构化数据,也就是抽象语法树(AST)
- Optimizer查询优化:SQL 是一门表意的语言,只是说「要做什么」,而不说「怎么做」。所以需要一些复 杂的逻辑选择「如何拿数据」,也就是选择一个好的查询计划。优化器的作用根据AST优化产生最优执行计划(Plan Tree)
- Executor查询执行:根据查询计划,完成数据读取、处理、写入等操作。
事务引擎:处理事务一致性、并发、读写隔离等
存储引擎:内存中的数据缓存区、数据文件(Data File)、日志文件(Log File)
SQL引擎
Parser
解析器(Parser)一般分为词法分析(Lexical analysis)、语法分析(Syntax analysis)、语义分析(Semantic analyzer)等步骤。
所有的代码在执行之前,都存在一个解析编译的过程, 差异点无非在于是静态解析编译还是动态的。
SQL语言也类似,在SQL查询执行前的第一步就是查询解析。
词法分析:将一条SQL 语句对应的字符串分割为一个个token,这些token可以简单分类。
语法分析:把词法分析的结果转为语法树。根据token序列匹配不同的语法规则,比如这里匹配的是update语法规则,类似的还有insert、 delete、 select、 create、 drop等等语法规则。根据语法规则匹配SQL语句中的关键字,最终输出一个结构化的数据
语义分析:对语法树中的信息进行合法性校验。
Optimizer
基于规则的优化(RBO:Rule Base Optimizer)
规则是预先定义好的,如
- 条件化简
- 表连接优化中的:总是小表先进行连接
- Scan优化中的:先进行唯一索引,再进行普通索引,再进行全表扫描
基于代价的优化(CBO:Cost Base Optimizer)
代价可能的考量标准:时间、IO、CPU、网络、存储
Executor
火山模型:
执行时由抽象的Operator算子拼接
Plan Tree为基础
调用关系是由根到叶
数据流是从叶到根向量化模型:
(Batch N行数据一起计算)
向量化执行更适合于大批量数据处理,对于很多单行数据处理并没有
优势。而且往往搭配列式存储使用。编译执行模型:
(将所有操作封装在一个函数中)
类比火山模型,就是将所有算子都合并在一起,这样可以大幅降低函数调用的代价
代码生成之后数据库运行时仍然是一个for循环,只不过这个循环内部的代码从简单的一个虚函数调用
plan.next()
展开成了一系列具体的运算逻辑,这样数据就不用再各个operator之间进行传递,而且有些数据还可以直接被存放在寄存器中,进一步提升系统性能。整个操作有点像inline函数,把所有的操作inline到一个函数中去。LLVM动态编译执行技术,根据优化器产生的计划,动态的生成执行代码。
存储引擎 - InnoDB
架构图如下图:
Buffer Pool
其中两个重要的部分:HashMap和LRU淘汰
HashMap:<page_id, block>的映射
LRU:MySQL对传统的LRU进行了优化,对Buffer Poll的数据进行了冷热分离;刚替换进内存的page存放在冷数据区,如果1s后被访问,加入热数据去;否则就放在冷数据区;
Page
没听懂捏
B+ Tree
很迷糊捏
事务引擎
Atomicity 与 Undo Log
Isolation 与 锁(也是借助Undo log)
读读:Share Lock
写写:Exclusive Lock,需要等待
读写:MVCC机制(相当于可以读到旧版本的数据)(也是借助Undo log)
Durability 与 Redo Log
WAL(Write-ahead Logging)借助Redo log
企业实践
Binlog
binlog是MySQL用来记录数据库表结构变更以及表数据修改的的二进制日志,它只会记录表的变更操作,但不会记录select和show这种查询操作。
数据恢复:误删数据之后可以通过mysqlbinlog工具恢复数据
主从复制:主库将binlog传给从库,从库接收到之后读取内容写入从库,实现主库和从库数据一致性
审计:可以通过二进制日志中的信息进行审计,判断是否对数据库进行注入攻击
- 本文链接:https://wan-nan.github.io/2023/02/11/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3RDBMS/
- 版权声明:本博客所有文章除特别声明外,均默认采用 许可协议。