这是我参与「第三届青训营-后端场」笔记创作活动的第19篇笔记。
1.发展历史
- 人工管理
- 文件系统
- DBMS:网状模型>>层次模型(树状)>>关系模型 ||网状模型|层次模型|关系模型| |-|-|-|-| 优势|能直接描述现实世界。存储效率较高|结构简单。查询效率高。可以提供较好的完整性支持|实体及实体间的联系都通过二维表结构表示。可以方便的表示M:N关系。数据访问路径对用户透明| 劣势|结构复杂。用户不易使用。访问程序设计复杂|无法表示M:N的关系。插入、删除限制多。遍历子节点必须经过父节点。访问程序设计复杂|关联查询效率不够高。关系必须规范化|
2.关键技术
2.1 SQL处理过程
发送SQL请求>>路由器收到请求并转发>>RDBMS开始处理>>结果返回用户。
处理过程:
- Parser解析SQL,形成语法树(AST)。
- Optimizer优化语法树,形成Plan Tree。
- Executor执行Plan Tree。
执行过程:读数据文件入缓存。写数据。写日志。
2.2 SQL引擎-Parser
解析器(Parser)一般分为词法分析(Lexical analysis)、语法分析(Syntax analysis)、语义分析(Semantic analyzer)等步骤。
- 词法分析:划分SQL语句的关键字、表列明、常量、算符、结束符。
- 语法分析:将关键词生成语法树。
- 语义分析:检查表、属性是否存在,检测常量是否可用。
2.3 SQL引擎-Optimizer
基于规则的优化:
- 条件简化:用户输入的逻辑化简。
- 表连接优化:总是小表先进行连接(连续连接时减少后续连接的表大小)。
- Scan优化:索引选择策略,唯一索引、普通索引、全表扫描中选取效率最高的方法。
基于代价的优化:考虑时间、IO、CPU、NET、MEM等资源。
2.4 SQL引擎-Executor
火山模型
每个算子(Operator)调用Next操作,访问下层算子,获得下层算子返回的一行数据,经过计算之后,将这行数据返回给上层。
优点:每个算子独立抽象实现,相互之间没有耦合,逻辑结果简单。
缺点:每计算一条数据有多次函数调用开销,导致CPU效率不高。
向量化模型
每个算子每次操作计算的不再是一行数据,而是一批数据(Batch N行数据),计算完成后向上层算子返回一个Batch。
优点:函数调用次数降低为1/N。CPU cache命中率更高。可以利用CPU提供的SIMD机制。
编译执行模型
将所有的操作封装到一个函数里,函数调用的代价也能大幅度降低。
用户的SQL语句不同编译出的文件也不同。所以需要用到动态编译技术。LLVM动态编译执行技术。
2.5 存储引擎-InnoDB
InnoDB分为两部分:In-Memory部分和On-Disk部分。
In-Memory:
- Buffer Pool
- Change Buffer
- Adaptive Hash Index
- Log Buffer
On-Disk:
- System Tablespace(ibdata1,存储元信息)
- General Tablespace(xxx.ibd,一般表,存储普通数据)
- Undo Tablespaces(xxx.ibu)
- Temporary Tablespaces(xxx.ibt,临时表)
- Redo Log(ib_logfileN)
Buffer Pool
根据page_id的哈希值确定位置。
使用LRU存储磁盘中的数据。(优化过的LRU。5/8为新节点,3/8为老节点。)
Page
| 变长字段列表 | NULL值标志位 | Header | row_id | trx_id | rool_ptr | Col1 | Col2 | Col3 | ... | ColN |
|---|
Header:
- delete_mask:标识此条数据是否被删除。
- next_record:下一条数据的位置。
- record_type:当前记录的类型。
2.6 事务引擎
原子性与重做日志
UndoLog是逻辑日志,记录增量变化。利用UndoLog可以进行事务回滚,从而保证事务的原子性。同时也实现了多版本并发控制(MVCC),解决读写冲突和一致性的问题。
隔离性与锁
MVCC的意义:
- 读写互不阻塞。
- 降低死锁概率。
- 实现一致性读。
UndoLog在MVCC的作用:
- 每个事务有一个单增的事务ID。
- 数据页的行记录中包含了DB_ROW_ID,DB_TRX_ID,DB_ROLL_PIR。
- DB_ROLL_PTR将数据行的所有快照记录都通过链表串联。
持久性与RedoLog
方案1:事务提交前写磁盘。
- 随机IO:由于数据是随机存储在磁盘的各个位置的,因此每次写都需要多次IO。
- 写放大:每次改动很小,但必须按照一个页面的最小单元(16K)去写。
方案2:redolog。
3.企业实践
3.1 大流量-Sharding
问题:单节点写容易成为瓶颈。单机数据库容量上限。
方案:业务数据水平拆分。代理层进行分片路由。
实施效果:数据库写入性能线性扩展。数据库容量线性扩展。
3.2 突增流量-扩容
问题:活动流量上涨。集群性能不能满足要求。
方案:扩容DB物理节点数量。利用影子表进行压测。
实施效果:数据库集群提供更高的吞吐。保证集群可以承担预期流量。
3.3 流量突增-代理连接池
问题:突增流量导致大量建联(建立连接)。大量建联导致负载变大,延时上升。
方案:业务侧预热连接池。代理侧预热连接池。代理侧支持连接队列。
实施效果:避免DB被突增流量打死。避免代理和DB被大量建联打死。
3.4 数据库稳定性&可靠性问题
3AZ高可用
- AZ(available zone)。三机房部署可以实现机房级别容灾、机房级别流量调度。
- proxy读写分离、分库分表,限流、流量调度。
- 监控报警实时监控集群运行状态,提前上报集群风险。 通过以上策略监控DB运行状态,在宕机时快速切换。
HA管理
问题:db所在机器异常宕机。db节点异常宕机。
方案:ha服务监管、切换当即节点。代理支持配置热加载。代理自动屏蔽宕机读节点。
4.问题答疑
- 何时使用B树做索引:数据在内存中,不涉及IO(PMEM,非易失性内存)。
- 查询缓存和buffer pool差别:查询缓存缓存了查询后的结果;bufferpool存储的是表数据,执行器在bufferpool上查询并形成查询结果。