这是我参与「第五届青训营」伴学笔记创作活动的第 16 天
深入理解RDBMS
发展历史
- 在现代计算机发明出来以前,通过人工的方式进行数据记录和管理
- 文件系统
- DBMS:按照某种数据模型来组织、存储和管理数据的仓库。
- 所以通常按照数据模型的特点将传统数据库系统分成网状数据库、层次数据库和关系数据库三类。
- 网状数据库:
- 层次数据库:
- 关系模型:
关键技术
- 一条SQL的一生
SQL引擎-Parser
- 解析器(Parser)一般分为词法分析(Lexical analysis)、语法分析(Syntax analysis)、语义分析(Semantic analyzer)等步骤。
Optimizer
- 基于规则的优化RBO
- 条件化简
- 表连接优化:总是小表先进行连接
- Scan优化
- 条件化简
- 基于代价优化CBO
- 一个查询有多种执行方案,CBO会选择其中代价最低的方案去真正的执行。--事件,资源
Executor
火山模型
- 每个Operator调用Next操作,访问下层Operator,获得下层Operator返回的一行数据,经过计算之后,将这行数据返回给上层。
优点:
- 每个算子独立抽象实现,相互之间没有耦合,逻辑结构简单
缺点:
- 每计算一条数据有多次函数调用开销,导致CPU效率不高。
向量化
- 每个Operator每次操作计算的不再是一行数据,而是一批数据(Batch N行数据),计算完成后向上层算子返回一个Batch。
编译执行
动态编译技术
- 将所有的操作封装到一个函数里面,函数调用的代价也能大幅度降低
- 用户SQL千变万化怎么办?难道要穷举用户的所有SQL,给每一个SQL都预先写好一个执行函数吗?
- 代码生成之后数据库运行时仍然是一个 for 循环,只不过这个循环内部的代码从简单的一个虚函数调用plan.next()展开成了一系列具体的运算逻辑,这样数据就不用再各个 operator 之间进行传递,而且有些数据还可以直接被存放在寄存器中,进一步提升系统性能。整个操作有点像inline 函数,把所有的操作inline到一个函数中去。
存储引擎-InnoDB
Buffer Pool
- 每个block对应一个page
- MySQL 的优化思路就是:对数据进行冷热分离,将 LRU 链表分成两部分,一部分用来存放冷数据,也就是刚从磁盘读进来的数据,另一部分用来存放热数据,也就是经常被访问到数据。
Page
B+ Tree
- 页面内: 页目录中使用二分法快速定位到对应的槽,然后再遍历该槽对应分组中的记录即可快速找到指定的记录。
- 从根到叶:中间节点存储
事务引擎
Undo Log是逻辑日志,记录的是数据的增量变化。利用Undo Log可以进行事务回滚,从而保证事务的原子性。同时也实现了多版本并发控制(MVCC) ,解决读写冲突和一致性读的问题。
Isolation与MVCC
MVCC的意义:
- 读写互不阻塞;
- 降低死锁概率;
- 实现—致性法
Undo Log在MVCC的作用: - 每个事务有一个单增的事务ID;
- 数据页的行记录中包含了DB_ROW_ID,DB_TRX_ID,DB_ROLL_PTR;
- DB ROLL PTR将数据行的所有快照记录都通过链表的结构串联了起来。
Durability与Redo
企业实践
- 问题:单节点写容易成为瓶颈,单机数据容量上限
- 业务数据进行水平拆分,代理层进行分片路由
- 问题:活动流量上涨,集群性能不满足要求
- 扩容DB物理节点数,利用影子表进行压测
- 问题:突增流量导致大量建联,大量建联导致负载变大,延时上升
- 业务侧预热连接池,代理侧预热连接池,代理侧支持连接队列
- 问题:稳定性和可靠性-3AZ高可用
-
BinLog:binlog是mysql用来记录数据库表结构变更以及表数据修改的的二进制日志,它只会记录表的变更操作,但不会记录select和show这种查询操作。
-
数据恢复:误删数据之后可以通过mysqlbinlog工具恢复数据
-
主从复制:主库将binlog传给从库,从库接收到之后读取内容写入从库,实现主库和从库数据一致性
-
审计:可以通过二进制日志中的信息进行审计,判断是否对数据库进行注入攻击
-
问题:db所在机器异常宕机,db节点异常宕机
- ha服务监管、切换宕机节点;代理支持配置热加载;代理自动屏蔽宕机读节点