MySQL
2024-04-12 10:51:21 11 举报
使用
MySQL的执行过程以及锁相关信息
作者其他创作
大纲/内容
页
Undo Log Record 2
Undo Log Record
低
锁
roll_pointer
LOCK_MODE
id=1
MTR1读
旧roll_pointer
tx_id=35
1. 获取链接2. 权限验证
旧事务ID
会出现
SELECT user_name FROM user WHERE id > 10 FOR UPDATE;
col_value=wang
LOCK_AUTO_INC:自增锁
undo log
......
REC_LOCK_TYPE
锁信息
Bin Log和Redo Log日志的写入会经过操作系统缓存
LOCK_IS:共享意向锁
Undo Log Segment Header
Undo Log Record 5
result
读已提交
数据文件
LOCK_GAP:GAP锁
type=INSERT
未提交
预处理器
col_value=zhang
type=DELETE
主键信息
read view
数据的读写不会经过操作系统缓存
读未提交
表ID
串行读
语法树
6. 刷到磁盘
bin log
行级锁
tx_id=40
TRX_UNDO_INSERT_REC
READ_COMMIT:每次读取时都会生成一个READ_VIEW
MTR3
读
操作信息
5. 写入page cache
8. 刷到磁盘
REPEATABLE_READ:只会在第一次读取时生成READ_VIEW
Change Buffer
脏读:事务1的过程中读取到了事务2中未提交的数据不可重复读:事务1执行过程中读取数据A两次,在两次读取之间,事务2对数据A进行了修改并提交,导致事务1两次读取数据A结果不一致幻读:事务1执行过程中对一个数据集合读取两次,在这两次读取之间,事务2对集合进行了增减操作,导致事务1两次读取的集合数量不一致
自适应哈希索引
ID=1
解决
Buffer Pool
被锁表信息(表锁)
3. 更新内存中的数据
LOCK_TYPE
SQL
tx_id=10
Undo Log Record 1
变长字段列表
SQL语句
被锁行行号(行锁)
LOCK_S:共享锁
col_value
LOCK_REC_NOT_GAP:精准行锁
Undo Log
Undo Log Record 4
执行计划
Undo Log Record 6
线程
服务端连接池
...
下一个将要分配的事务ID
参数
执行器
锁的类型和模式信息
基本信息
redo log
7. 写入Bin Log
精准行锁与行GAP锁的组合
被更新信息
不可重复读
1. 数据预读到内存
Redo Log Buffer
可重复度
加锁时,在表上做了一个标记,表示这个表已经加锁了,其他事务在加锁前就不需要遍历每一行数据来判断当前表是否有锁了
LOCK_TABLE:表锁
SQL模版
Null值列表
col_value=chen
头信息
锁住精准对应的行
被锁的索引信息
Page Cache
File Header
服务端
min_trx_id
命令(增删改查)
Undo Log Record
语法分析器
数据字典
Undo Log Record 3
高
MTR2写
Undo Log Page
脏页
LOCK_X:独占锁
4. 写入Redo Log
File Tailer
type
当前活跃的事务集合(未提交)
col_value=qian
TRX_UNDO_UPD_EXIST_REC
创建当前视图的事务ID
IO线程
SQL优化器
Redo Log刷盘策略:1. innodb_flush_log_at_trx_commit=0:每隔1S中将Redo Log Buffer中的数据写入page cache并刷到磁盘2. innodb_flush_log_at_trx_commit=1:每次提交事务的时候都会把rodo log写入page cache并刷到磁盘3. innodb_flush_log_at_trx_commit=2:事务提交的时候会写入Redo Log Buffer和page cache,每隔1S进行刷盘操作
SQL接口
Undo Log Buffer
表级锁
Tocken
type=UPDATE
tx_id=9
对整张表进行加锁,在释放之前拒绝其他任何事务操作这张表的任何数据
10. 写入磁盘
上锁事务的信息
当前集合最小事务ID
9. 将commit操作写入Redo Log
幻读
LOCK_REC:行锁
ID=2
merge
mysql
MySQL数据库默认的隔离级别是可重复读(REPEATABLE-READ),并且通过MVCC解决了脏读,不可重复读和幻读问题
自增锁与事务无关,即使多个insert在一个事务中,每次insert也会申请自增锁
特有信息
Handler API
客户端连接池
1. 如果被访问的版本的事务ID等于当前创建视图的事务ID,则意味着读取自己当前事务,所以该版本可以被当前事务访问2. 如果被访问的版本的事务ID小于当前视图集合中最小的事务ID,则意味着该版本的事务在视图生成之前就已经提交,所以该版本可以被当前事务访问3. 如果被访问的版本的事务ID大于当前视图集合中最大的事务ID,则意味着该版本的事务在生成视图的时候还未提交,所以该版本不能被当前事务访问4. 如果被访问的版本的事务ID介于当前视图集合中最大和最小事务ID之间: (1)如果该版本的事务ID在活跃的事务集合列表里面,则意味着该版本的事务在生成视图的时候还未提交,所以该版本不能被当前事务访问 (2)如果该版本的事务ID不在活跃的事务集合列表里面,则意味着该版本的事务在视图生成之前就已经提交,所以该版本可以被当前事务访问5. 如果当前版本不可被当前事务访问,则遍历版本链,获取下一个被访问的版本继续根据1-4步进行判断
max_trx_id
脏读
LOCK_ORDINARY:Next Key锁
m_ids
creator_trx_id
LOCK_IX:独占意向锁
Undo Log Header
数据写入过程:1. 在更新数据的时候,如果Buffer Pool中不存在这条数据会先从磁盘中将该数据读入内存Buffer Pool 中2. 在修改数据前,需要先将数据写入Undo Log中3. 在数据写入完Undo Log后会更新内存中的数据4. 更新完内存中的数据后会将数据写入Redo Log Buffer,然后以一定的频率将redo log buffer 写入磁盘5. 在写redo log的同时,mysql server会写入bin log到磁盘缓存,然后以一定频率刷到磁盘bin log文件6. 最后后台IO线程再将数据以一定的频率写入到磁盘
Undo Page Header
Bin Log刷盘策略:1. sync_binlog=0:事务提交时立即将bin log写入page cache,由操作系统决定什么时候进行刷盘2. sync_binlog=1:事务提交时立即将bin log写入page cache,并进行刷盘操作3. sync_binlog=n:事务提交时立即将bin log写入page cache,每当提交n次事务后进行刷盘操作
一种特色的GAP锁,也是共享锁
SELECT user_name FROM user WHERE id > 10 LOCK IN SHARE MODE;
并发度
词法分析器
锁住行与行之间的间隙,防止行间隙间插入数据
表空间+页号(行锁)
tx_id=20
2. 将数据写入Undo Log
SQL解析器
对表内的部分行进行加锁,行锁加载数据中或者索引中
TRX_UNDO_DEL_MARK_REC
InnoDB
执行结果
LOCK_INSERT_INTENTION:插入意向锁
select/update
已提交
隔离性
0 条评论
下一页