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#…