• 数据库事务的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传给从库,从库接收到之后读取内容写入从库,实现主库和从库数据一致性

    审计:可以通过二进制日志中的信息进行审计,判断是否对数据库进行注入攻击