架构
内存架构
buffer pool
change buffer
自适应哈希
log buffer
磁盘架构
sql执行流程图
死锁
锁
表锁
意向锁
在对某一个数据加行锁时,会先加一个表级别的意向锁;另一个事务若需要添加表级别的锁时,会与意向锁判断看是否有冲突。
行锁
间隙锁
主要用来解决幻读
插入意向锁
插入意向锁,听起来似乎跟前面的表级别意向锁有些类似,但实际上插入意向锁是一种间隙锁,这种锁是一种隐式锁,也就是咱们无法手动的获取这种锁。通常在MySQL
中插入数据时,是并不会产生锁的,但在插入前会先简单的判断一下,当前事务要插入的位置有没有存在间隙锁或临键锁,如果存在的话,当前插入数据的事务则需阻塞等待,直到拥有临键锁的事务提交。
作者:竹子爱熊猫
链接:https://juejin.cn/post/7153869469394305061
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
undo log 撤销日志
MVCC
由来
基于读-写并存的场景,推出了MVCC
机制,在线程安全问题和加锁串行化之间做了一定取舍,让两者之间达到了很好的平衡,即防止了脏读、不可重复读及幻读问题的出现,又无需对并发读-写事务加锁处理。
做到即使有读写冲突时,也可以不加锁解决,从而确保了任何时刻的读操作都是非阻塞的
仅在RC
读已提交级别、RR
可重复读级别才会使用MVCC
机制
原理
多版本依赖Undo-log版本链
,并发控制通过表的隐藏字段+ReadView
快照来实现。
隐藏字段
row_id:如果没有主键,会默认添加一个递增的row_id。(原因:聚簇索引需要)
deleted_bit:删除标识,并不是真正的删除
trx_id:记录改动某条数据的事务id
roll_ptr:回滚指针,指向这条数据的老数据版本(老数据在undo log中)
undo log版本链
readView
一个事务在尝试读取一条数据时,MVCC
基于当前MySQL
的运行状态生成的快照,也被称之为读视图。
creator_trx_id
:代表创建当前这个ReadView
的事务ID
。trx_ids
:表示在生成当前ReadView
时,系统内活跃的事务ID
列表。up_limit_id
:活跃的事务列表中,最小的事务ID
。low_limit_id
:表示在生成当前ReadView
时,系统中要给下一个事务分配的ID
值。
RC
级别下,MVCC
机制是会在每次select
语句执行前,都会生成一个ReadView。
RR
级别中,一个事务只会在首次执行select
语句时生成快照,后续所有的select
操作都会基于这个ReadView
来判断。
隔离级别
①Read uncommitted/RU
:读未提交
②Read committed/RC
:读已提交
③Repeatable read/RR
:可重复读(默认)
幻读问题
select 某记录是否存在,不存在,准备插入此记录,但执行insert时发现此记录已存在,无法插入。
④Serializable
:序列化/串行化
redo log
流程:数据先写入redo log(先写道redo log buffer中,再根据策略落redo log),然后再写入内存中,后台线程将根据redo log中(write pos和check point)的数据落到表中。
Innode 引擎才有
内存写入数据前,会先写日志
两阶段提交
redo log buffer落盘时机:
为何不直接落磁盘,而是先写redo log再写入内存,再落盘?
- 重启情况,内存中数据丢失,可以恢复。
- redo log尾部直接追加,顺序写入,落盘是随机写入,比较慢。
Binlog
所有引擎都有
记录所有对数据库表结构变更和表数据修改的操作
redo 和bin log区别
①生效范围不同,Redo-log
是InnoDB
专享的,Bin-log
是所有引擎通用的。
②写入方式不同,Redo-log
是用两个文件循环写,而Bin-log
是不断创建新文件追加写。
③文件格式不同,Redo-log
中记录的都是变更后的数据,而Bin-log
会记录变更SQL
语句。
④使用场景不同,Redo-log
主要实现故障情况下的数据恢复,Bin-log
则用于数据灾备、同步。
参考:
(十一)MySQL日志篇之undo-log、redo-log、bin-log.....傻傻分不清! - 掘金
彻底搞懂MySQL的redo log,binlog,undo log - 掘金
(九)MySQL之MVCC机制:为什么你改了的数据我还看不见? - 掘金
(七)MySQL事务篇:ACID原则、事务隔离级别及事务机制原理剖析 - 掘金
MySQL幻读详解及解决方法_学而不思则忘的博客-CSDN博客_mysql 幻读