buffer pool
提高读写性能
缓冲池是一片内存区域,存储引擎在读取数据时,会先将页读取到缓冲池中。下次读取时,先判断是否在缓冲池,如果在,则直接读取,否则从磁盘中读取。在修改数据时,如果缓冲池中不存在所需的数据页,则从磁盘读入缓冲池,否则直接对缓冲池中的数据页进行修改。
由于这个刷脏页的过程还是异步的,这样更新操作就不需要等待磁盘的 IO 操作了。因此这些特点极大地提升了 InnoDB 的性能。
大小
默认是128MB,可以根据物理内存调整,一般建议设置为60%~80%
内容
管理
如何提高缓存命中率
采用类似LRU算法,但是LRU算法有两个问题
预读失效
MySQL 在加载数据页时,会提前把它相邻的数据页一并加载进来,目的是为了减少磁盘 IO。但是可能这些被提前加载进来的数据页,并没有被访问,相当于这个预读是白做了,这个就是预读失效
解决:
改进了 LRU 算法,将 LRU 划分了 2 个区域:old 区域 和 young 区域。
过程:划分这两个区域后,预读的页就只需要加入到 old 区域的头部,当页被真正访问的时候,才将页插入 young 区域的头部。如果预读的页一直没有被访问,就会从 old 区域移除,这样就不会影响 young 区域中的热点数据。
buffer pool污染
比如,在一个数据量非常大的表,执行了这条语句:
select * from t_user where name like "%xiaolin%";
过程:
- 从磁盘读到的页加入到 LRU 链表的 old 区域头部;
- 当从页里读取行记录时,也就是页被访问的时候,就要将该页放到 young 区域头部;
- 接下来拿行记录的 name 字段和字符串 xiaolin 进行模糊匹配,如果符合条件,就加入到结果集里;
- 如此往复,直到扫描完表中的所有记录。
经过这一番折腾,原本 young 区域的热点数据都会被替换掉。怎么解决出现 Buffer Pool 污染而导致缓存命中率下降的问题?
MySQL 是这样做的,进入到 young 区域条件增加了一个停留在 old 区域的时间判断。
具体是这样做的,在对某个处在 old 区域的缓存页进行第一次访问时,就在它对应的控制块中记录下来这个访问时间:
- 如果后续的访问时间与第一次访问的时间在某个时间间隔内,那么该缓存页就不会被从 old 区域移动到 young 区域的头部;
- 如果后续的访问时间与第一次访问的时间不在某个时间间隔内,那么该缓存页移动到 young 区域的头部;
binlog
binlog 是 MySQL 服务器层面实现的一种二进制日志,用于记录所有对数据库的增删改操作,主要有两个作用
- 数据库的备份与恢复
- 主从复制
binlog有三种模式:row模式,stat模式和混合模式
redo log
是用来恢复数据用的日志。前面我们讲到数据页在缓冲池中被修改会变成脏页。如果这时宕机,脏页就会失效,这就导致我们修改的数据丢失了,也就无法保证事务的持久性。保证数据不丢,就是 redo log 的一个重要功能
redo log 是顺序写(顺序 IO),因此能有效提升 IO 效率;又因为每次事务提交前会先写 redo log,因此可以保障更新的数据不丢失。
mysql写顺序
先写undolog、redolog-pre、binglog、redolog-commit、写buffer、提交事务
提交事务后,redolog可以覆盖了
参考:
https://juejin.cn/post/7130612183771119652
https://xiaolincoding.com/mysql/buffer_pool/buffer_pool.html#…
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
相关推荐: Android平台如何实时叠加电量信息和设备信号状态到GB28181接入端
技术背景 我们在Android平台实现GB28181设备接入,把摄像头和麦克风数据,采集过去,用于移动单兵、智能车载、智慧安防、智能家居、工业仿真等行业时,发现大多场景对视频水印的要求越来越高,从之前的固定位置静态文字水印、png水印等慢慢过渡到动态水印需求。…