mysql行级锁使用教程(浅析MySQL的lru链表)
mysql行级锁使用教程
浅析MySQL的lru链表一、简述传统的lru链表
lru:least recently used
相信大家对lru链表是不陌生的,它算是一种基础的数据结构吧,而且想必面试时也被问到过什么是lru链表,甚至是让你手写一个lru链表。
如果你读了上一篇:你有没有搞混查询缓存和bufferpool?谈谈看!
想必你已经知道了mysql的buffer pool机制以及mysql组织数据的最小单位是数据页。并且你也知道了 数据页在buffer pool中是以lru链表的数据结构组织在一起的。
其实所谓的lru链表本质上就是一个双向循环链表,如下图:
下面我们结合lru链表和数据页机制描述一下mysql加载数据的机制:
我们将从磁盘中读取的数据页称为young page,young page会被直接放在链表的头部。已经存在于lru链表中数据页如果被使用到了,那么该数据页也被认为是young page而被移动到链表头部。这样链表尾部的数据就是最近最少使用的数据了,当buffer pool容量不足,或者后台线程主动刷新数据页时,就会优先刷新链表尾部的数据页。
二、传统lru链表的不足
相信你之前肯定听说过操作系统级别的空间局部性原理:
spatial locality(空间局部性):也就是说读取一个数据,在它周围内存地址存储的数据也很有可能被读取到,于是操作系统会帮你预读一部分数据。
mysql也是存在存在预读机制的!
- 当buffer pool中存储着一个区中13个连续的数据页时,你再去这个区里面读取,mysql就会将这个区里面所有的数据页都加载进buffer pool中的lru链表中。(然后可能你根本不会使用这些被预读的数据页)
- 当你顺序的访问了一个区中大于 innndb_read_ahead_threshold=56个数据页时,mysql会自动帮你将下一个相邻区中的数据页读入lru链表中。(这个机制默认是被关闭的)
- 当你执行select * from xxx;时,如果表中的数据页非常多,那这些数据页就会一一将buffer pool中的经常使用的缓存页挤下去,可能留在lru链表中的全部是你不经常使用的数据。
综上你可以看到,所谓的预读机制的优势,实际上违背了lru去实现将最近最少使用的数据页刷入磁盘的设计初衷。
三、mysql的lru链表
接下来我们看下mysql的buffer pool是如何定制lru链表的,已经lru帮innodb解决了什么问题。
当业务进行大量的crud时,需要不断的将数据页读取到buffer pool中的lru链表中。
mysql的lru链表长下面这样。
lru链表被midpoint分成了new sublist和old sublist两部分。
其中new sublist大概占比5/8,old sublist占比3/8。
new sublist存储着young page,而old sublist存储着old page。
我们可以通过如下的方式查看midpoint的默认值。
用户可以根据自己的业务动态的调整这个参数!
这其实是一种冷热数据分离设计思想。他相对于传统的lru链表有很大的优势
四、mysql定制lru链表的优势
而对于mysqllru链表来说,通过midpoint将链表分成两部分。
从磁盘中新读出的数据会放在old sublist的头部。这样即使你真的使用select * from t;也不会导致new sublist中的经常被访问的数据页被刷入磁盘中。
正常情况下,访问old sublist中的缓存页,那么该缓存页会被提升到new sublist中成为热数据。
但是当你通过 select * from t 将一大批数据加载到old sublist时,然后在不到1s内你又访问了它,那在这段时间内被访问的缓存页并不会被提升为热数据。 这个1s由参数innodb_old_blocks_time控制。
另外:new sublist也是经过优化的,如果你访问的是new sublist的前1/4的数据,他是不会被移动到lru链表头部去的。
以上就是浅析mysql的lru链表的详细内容,更多关于mysql lru链表的资料请关注开心学习网其它相关文章!
原文链接:https://www.cnblogs.com/ZhuChangwu/p/13983648.html
- navicat for mysql连接测试失败(Navicat Premiun远程连接MySQL报错10038解决方案)
- mysql云数据库数据恢复(MySQL 利用frm文件和ibd文件恢复表数据)
- mysqldata数据如何恢复(mysql5.7.33误删除ibdata文件找回数据的方法)
- mysqljoin语句用法(MySQL的join buffer原理)
- mysql读写分离同步策略(Mysql主从复制与读写分离图文详解)
- 创建数据库入门教程mysql(MySQL数据库安装教程一学就会)
- mysql根据子节点查询父节点(mysql 递归查找菜单节点的所有子节点的方法)
- mysql查看死锁记录(mysql查看死锁与去除死锁示例详解)
- mysql 存储引擎有哪些(MySQL 常见存储引擎的优劣)
- mysql8.0.16安装步骤图解(mysql 8.0.22 安装配置图文教程)
- 如何正常查看mysql存储数据文件(Mysql文件存储图文详解)
- mysql实用教程(Mysql调优Explain工具详解及实战演练推荐)
- mysql中的null和空值的区别(解决mysql使用not in 包含null值的问题)
- mysql并发查询优化(详解MySQL 联合查询优化机制)
- mysql类型转换函数推荐(mysql 数据类型转换的实现)
- mysql创建存储过程的代码(MySQL修改存储过程的详细步骤)
- 这部民警编演的红色话剧,讲述了一个不断追寻的故事(这部民警编演的红色话剧)
- 日本菜有什么好吃(日本菜有什么好吃的做法)
- 韩国泡菜做法(韩国泡菜的做法步骤)
- 泰国旅游攻略(泰国旅游攻略必去景点)
- 越难春卷(越难春卷皮怎么用)
- 休闲VS新古典 办公家居简约设计(办公家居简约设计)
热门推荐
- 如何注册asp.net 4.0 到iis
- python密码错误3次不能再输入(Python实现账号密码输错三次即锁定功能简单示例)
- python分步式进程计算(python中如何使用分步式进程计算详解)
- docker执行shell脚本(基于Docker搭建ELK 日志系统的方法)
- css弹性布局设置每行显示指定个数(CSS实现多行多列的布局的实例代码)
- iframe嵌入页面跨域(使用iframe+postMessage实现页面跨域通信的示例代码)
- sql server查询语句语法(详解SQL Server的简单查询语句)
- js获取微信版本号
- python弹球游戏编写过程(python实现坦克大战游戏 附详细注释)
- mysql修改表内字段的数据类型(mysql修改记录时update操作 字段=字段+字符串)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9