MySQL逻辑架构
1客户端
2连接/线程处理
3查询缓存
4分析器
5优化器
6存储引擎
整体概念先有
事务
ACID -> 原子性,一致性,隔离性,持久性
-
隔离级别(针对隔离性)
- Read Uncommitted(读未提交) -> 在事务中的修改,即使不提交,别的事务也是可见的,会有脏读问题
- Read Committed(读提交) -> 只能读取别的事务提交的数据 会有不可重复读问题
- Repeatable Read(可重复读) -> 在事务开启时,多次读取同一条数据,一定是一致的 可能有幻读的问题,InnoDB通过MVCC解决了这个问题
可重复读是MySQL的默认事务隔离级别.注意幻读是指读取范围数据时可能会读取到别的事务新插入的数据,也就是前后两次读取数据不一致 - Serializable(可串行化) -> 强制事务串行化执行
事务日志 -> 采用追加的方式,将事务内容写到磁盘上一块顺序I/O区域(不用真实的去进行随机I/O操作数据),然后再异步的将事务日志读取,并真实执行内容,因此修改数据需要写两次磁盘
-
多版本并发控制(MVCC)
MVCC的实现是通过保存数据在某个时间点的快照来实现的.也就是说根据事务开始时间的不同,同一时刻看到的数据可能是不一样的
InnoDB的MVCC是通过每行记录多保存2个隐藏的列实现的(系统版本号,过期版本号) -> 把版本号当做时间看
- select
1. 只查找版本早于当前事务的数据行 -> 过滤掉别的事务的更改
2. 行的删除版本,要么未定义,要么大于当前版本号 -> 确保在事务开始之前数据未被删除 - insert
更新当前版本号 - delete
更新删除版本号 -
update
1插入
一行新纪录,保存当前版本号
2同时保存当前版本号到原来的行(上一条)
作为行删除标识
通过增加版本号,使得大多数读操作不用加锁
注意MVCC是为了实现可重复读,只是一种实现隔离级别的技术手段
- select
锁
- 并发控制 -> 读写锁,表锁,行锁
- 死锁 -> 资源锁环形引用
- 隐式锁定
InnoDB采用的是"两阶段锁定协议” -> 在事务执行过程中,随时可以锁定数据,只有在commit和rollback时才会释放锁(所有的锁都是同一时刻被释放) - 显式锁定 -> 不建议
select … lock in share mode
select … for update