MySQL内部结构事务锁机制
2021-01-25 22:01:54 8 举报
MySQL直播
作者其他创作
大纲/内容
BP2
freed_page_lock:bp淘汰页数只有在热数据区域的后3/4部分的缓存页被访问
服务器部署java:4核8G的机器部署普通的Java应用系统,每秒大致就是抗下几百的并发访问mysql:用8核16G以的机器每秒抗个一两千并发请求是没问题的16核32G的机器更加合适每秒抗个两三千,甚至三四千的并发请求也都是可以的硬盘:SSD固态硬盘QPS:每秒可以处理多少个请求TPS:没秒可以处理多少事务io相关压测指标IOPS:这个指的是机器的随机IO并发处理的能力吞吐量:这个指的是机器的磁盘存储每秒可以读写多少字节的数据量数据库压测工具:sysbench
基于Undolog
页内记录维护
1:先查询缓存有没有
文件头:38字节 数据页描述
DB_Row_Id
表级锁
LRU链表尾指针
当前读
共享锁(S)读锁
描述数据
数据页
一组数据区(256个数据区)
sn-1
脏读(读取未提交的数据)
排他锁(X)写锁
io线程
页内记录维护顺序保证物理有序:逻辑有序:链表插入策略自由空间链表:先插入标记已经删除的记录位置(注意定期收缩表空间)未使用空间:页内查询遍历二分:从S二分查找
多个线程访问BP优化化
事务特性
binlog 日志文件对users表中的id=10的一行数据做了更新操作,更新以后的值是什么
行锁
定时执行
sn
是:不可见
MySQL服务器
删除基于最小活跃事务ID
数据区(包含64个l连续数据页1MB)
可重复读(默认隔离级别)RR(repeat read)隔离可能幻读
分别对应不同的工作线程
表空间(表名.ibd)
磁盘文件
他里面需要记录的就是表空间号+数据页号+偏移量+修改几个字节的值+具体的值
C(一致性)
所有需要全部加载到内存
最后一个优先淘汰
线程2
7:同时写入binlog
数据行
按照redo log block写入磁盘
所属表空间
已删除记录
6:事务提交时写入磁盘
改进
执行器
Record_TRX_ID>最大ID
否
update ... (更新操作)delete ... (删除操作)insert ... (插入操作)select ... lock in share mode (共享读锁)select ... for update (写锁)
当前事务ID
快照读
描述数据大概相当于缓存页大小的5%左右
SQL语句
解决可重复度模式下的幻读问题锁的是两次当前读之前的GAP
线程1
数据页刚加载在冷数据头部
数据页FSP_HDR
(淘汰机制)LRU就是Least Recently Used
当你的数据库启动之后,你随时可以通过上述命令,去查看当前innodb里的一些具体情况,执行SHOW ENGINEINNODB STATUS就可以了
Innodb_flush_log_at_trx_commit
回滚对应undo位置
查询优化器
只解决了当前读幻读问题
数据页编号
幻读(读取到别的事务未提交的新数据)
定时程序执行
sn-3
读取未提交Read uncommitted存在脏读
对那些数据进行了修改
第一次加载或修改更新页描述数据
使用了MVCC无法计数数量
数据头(40bit)00(无用)1(delete_mask是否删除)1(min_rec_maskB+非叶子节点最小值标记)0000(n_owned)(13bit heap_no在记录堆的位置)(3bit record_type数据类型 0代表的是普通类型,1代表的是B+树非叶子节点,2代表的是最小值数据,3代表的是最大值数据)(16bit next_record)
SQL分词 解析
建议:buffer pool总大小=(chunk大小 * buffer pool数量)的倍数
连接
SQL接口
page Hash数据页指针(数据页)表空间号+数据页号=缓存页地址
sn-2
Record_TRX_ID<最小ID
midpoint
数据页IBUF_BITMAP
缓存页
间隙锁
不可重复读(二次读取结果不同)
BP1
页尾:8字节 校验
有效数据记录11
有效数据记录1
MYSQL锁的实现
冷数据区域
数据页(16KB)
锁粒度
SQL解析器
读已提交Read Committed不能重复度
锁的类型(都是作用在索引上)聚簇索引&二级索引
行数据存放变长字段的长度列表(逆序存储)null值列表(101010二进制标识那个字段为null 1:null)数据头column0的值column1的值
5:写redo log
MVCC
页头:56字节 左右兄弟指针,空间使用情况
可见
锁类型
最后一次加载或修改更新页描述数据
DB_TRX_Id当前事务ID
可被多个事务获取,但阻止事务对行数据修改
内存文件
flush链表
工作线程1
最小虚记录(主键)
执行SQL(增删改改查)
连接池
是
DB_ROLL_PTR回滚ID
LRU中淘汰
基础节点 count=n
Free list获得地址
MyISAM
Tomcat
未分配空间
3:保存老数据到日志,事务回滚使用
执行计划
回滚指针找到上个版本
9:刷新buffer数据到磁盘
页面装载哪些情况下会触发MySQL的预读机制呢?innodb_read_ahead_threshold,他的默认值是56,意思就是如果顺序的访问了一个区里的多个数据页,访问的数据页的数量超过了这个阈值,此时就会触发预读机制,把下一个相邻区中的所有数据页都加载到缓存里去innodb_random_read_ahead:默认关闭 里缓存了一个区里的13个连续的数据页,而且这些数据页都是比较频繁会被访问的,此时就会直接触发预读机制,把这个区里的其他的数据页都加载到缓存里去全表扫描会导致整个表数据也加载到BP中
表行数据增加2字段
数据页XDES
LRU链表头指针
bp满了
默认:128M可通过innodb_buffer_pool_size修改
行溢出如blob等边长数据,真实数据部分会放到下页下页
Buffer Pool(128M)
描述信息
个innodb_old_blocks_time:1000ms在1秒后有访问的话直接加入热数据头部
MVCC读取流程
3次加载或修改更新页描述数据
二分查找页内数据
会把LRU链表的冷数据区域的尾部的一些缓存页,刷入磁盘里去,清空这几个缓存页,把他们加入回free链表去!
A(原子性)
RR隔级别使用
Read View活跃事务列表列表中最小事务ID列表最大事务ID
最优查询路径
Buffer Pool内存空间管理(3个链表维护)
2次加载或修改更新页描述数据
磁盘到内存加载顺序
线程3
可见性判断创建快照这一刻,已经提交的事务才能看到不然根据Read View里面3个属性判断是否可读等
Memory
是不可见
接收到SQL
隔离级别
InnoDB select count(*) from table 为什么慢
sync_binlog1:写入os cache2:写入磁盘
redo log buffer
undo日志文件记录修改前数据
并发问题
获得一个连接
D(持久性)
只能被一个事务获得,允许获得锁的事务修改数据
连接器:验证账号秘密设置表库执行权限接收传递SQL
自由空间链表
热数据区域
初始淘汰
8:写入事务对那个binlog文件名及更新位置同时写入commit标记
fush链表中的一波缓存页被刷入了磁盘,那么这些缓存页也会从flush链表和lru链表中移除,然后加入到free链表
Innodb存储引擎
有效数据记录10
LRU冷热分离 (2个LRU链表)冷热数据的比例是由innodb_old_blocks_pct参数控制的,他默认是37,也就是说冷数据占比37%。
发送请求
LRU_Flush
redo 日志文件记录修改的数据在系统崩溃时用于恢复事务修改顺序写性能好
I(隔离性)
最大虚记录(26bit)
串行化(一般不用)性能太大
4:更新缓存数据
有效数据记录9
Record_TRX_ID在活跃列表
ReDo日志
数据库连接池
flush链表记录要刷新的数据页(脏数据页)
Buffer Pool
数据页INODE
innodb_flush_log_at_trx_commit0:不会把redo log buffer里的数据刷入磁盘文件1:提交事务的时候,就必须把redo log从内存刷入到磁盘文件里去2:redo日志写入磁盘文件对应的os cache缓存里去1后写入磁盘,而不是直接进入磁盘文件
在BP中地址
同结构 free 链表记录空闲位置(空闲页)
0 条评论
下一页