mysql
文章目录
基础篇
sql执行流程
- 连接器:简历连接、管理连接、校验用户身份
- 解析sql:此法语法分析,构建语法树
- 执行sql
- 预处理阶段:检查表或字段是否存在
- 优化阶段:最小查询成本的执行计划
- 执行阶段:按执行计划执行sql
EXPLAIN 详解
type
- select_type
- type(system > const > eq_ref > ref > range > index > all)
- system、const 常量记录数
- eg_ref 主键或唯一索引被连接
- ref 普通索引,多个符合条件的记录行
- range 范围查询
- index 扫描全表索引,一般是某个二级索引
- ALL 全表扫面
- possible_keys 可能用到索引
- key 实际索引
- rows 读取行数
- extra列
- use index 覆盖索引
- use where 使用where语句,字段未被索引覆盖
- use index condition 查询的列不完全被索引覆盖
- useing temporary 临时表要优化
- useing filesort 外部排序不是索引排序,数据小内存,大磁盘
索引篇
索引失效
- 左或左右模糊匹配
- 对索引使用函数
- 对索引进行表达式计算
- 对索引使用隐形转换
- 联合索引非最左匹配;
index(a,b,c) where a=1 and c=3
索引截断,5.6版本后锁、索引下推减少回表次数 - where 子句中的 or;
where id=1 or age = 10
对 age 加索引 可以走index merge
避免全表扫描
索引区别
- exist 子查询使用索引
- not exist 主子查询使用索引
- in 与子查询一起,只能主查询使用索引
- not in 不使用索引
事务篇
特性 ACID
持久性 redo log(重做日志)
原子性 undo log(回滚日志)
隔离性 mvcc(多并发版本控制)
一致性则通过持久性+原子性+隔离性来保证
并发引起事务问题?
同时多个事务的时候,可能出现脏读、不可重复读、幻读等问题
脏读,读到其他事务未提交的数据;。
不可重复读,前后读取的数据不一致;。
幻读,前后读取的记录数量不一致。
隔离级别
读未提交
读提交
可重复读(默认),很大程度上避免了幻读,开启事务后尽快执行 select…for update 当前读使用next-key lock避免
串行化,会对记录加上读写锁
锁篇
日志篇
内存篇
架构设计
缓存设计
缓存失效
过期时间设置不合理,大量key同时过期,导致数据库压力,可能雪崩
解决:错开各key过期时间及分批次刷新
缓存穿透
数据库不存在的记录
- 现在记录不存在,不表示一直不存在
- 可能存在大量值为空的垃圾记录(攻击居多)
解决方法:
- 布隆过滤器Bloom Filter,空间效率很高的随机数据结构,位数组很简洁标识一个集合,高效判断元素是否存在(比如黑名单,不存在的id加入)
缓存一致性
参看三种经典的缓存模式
热点数据
- 极热点数据,可设置永不过期(或长时间不过期),定时刷新
数据迁移与同步
动态数据迁移
- 性服务线上sql脚本和es初始化
- 导出老服务全量数据(db和es),并记录时间点t1时刻
- 迁移全量数据(db和es)
- 新服务上线
- 老服务加入切流量功能后上线,切流量开关默认关闭
- 灰度发布
- 新服务以测试域名上线,与老服务同时运行
- 打开切流量开关,让部分用户流入到新服务,尽量选流量小时刻
- 新服务稳定后,全部切到新服务上,老服务下线,切流完成,记录t2时刻
- 增量数据迁移,查询全量数据t1时刻到t2时刻的,这段时间老服务新增或更新的数据库并迁移到新服务
静态数据迁移
数据变化小,一段时间不可用,直接导出迁移
一致性方案
强一致性
写入什么,读出来什么,体验好,实现对系统的影响大
弱一致性
写入后,不承诺可以读到写入的值,尽可能在某个时间级别(秒级别),数据达到一致
最终一致性
弱一致性的一个特例,系统保证在一定时间内,能够达到一个数据一致的状态。
三种经典的缓存模式
旁路缓存模式(Cache-Aside Pattern)
读流程
- 读的时候,先读缓存,命中缓存的话,直接返回数据。
- 缓存没有命中的话,就去读数据库,从数据库取出数据,放入缓存后,同时返回响应。
写流程
- 先更新数据库,再删除缓存。
Read-Through/Write-Through(读写穿透)
Read-Through
- 从缓存读取数据,读到直接返回
- 如果读取不到的话,从数据库加载,写入缓存后,再返回响应。
与Cache-Aside比,多了一层
Cache-Provider
封装。
Write behind (异步缓存写入)
Write behind跟Read-Through/Write-Through有相似的地方,都是由 Cache Provider
来负责缓存和数据库的读写。它两又有个很大的不同:Read/Write Through是同步更新缓存和数据的,Write Behind则是只更新缓存,不直接更新数据库,通过批量异步的方式来更新数据库。
文章作者 小叨
上次更新 2023-05-04