InnoDB关键特性,innodb_old_blocks_time,锁,内存管理,latch争用

本文深入探讨了InnoDB内存管理的free、lru、flush链的原理与作用,分析了锁的类型、latch争用的原因及解决办法,并详细介绍了插入缓冲、双写缓冲、自适应哈希索引等关键特性,旨在优化数据库并发访问与内存使用效率。
摘要由CSDN通过智能技术生成

声明:本博客所有文章均为博主原创,请勿非法复制。请勿盗取原创图片。


1.内存管理

  • 1.需要经常找free数据块; free list(free链)
  • 2.需要经常找冷的数据块; lru list(最近最少使用链)
  • 3.就需要系统将这些logfile对应的脏块,写入到磁盘上。flush list(按照脏的早晚链起来的链)

默认2个logfile,每个20M。logfile小了,容易hang住。

一个数据库最基本的调整

  • 增加组数;
  • 增加logfile大小;
  • 增加写线程的数量。

需要3种链(chain)
一种链一种作用。
一个个体可以在多个链上。
(比如同是一个班的学生,1.按高矮链起来 2.按男女链起来…)
对于链来说,我们需要进行遍历。

为什么要引入free,lru,flush list三种链

内存管理:
读线程将数据页从磁盘中调入内存之中时,会首先寻找free数据块,如果有free数据块,就将新来的数据放入free数据块中;如果没有free,就会寻找冷数据块,放入冷数据块中。而存储中的logfile文件也存在着轮转覆盖,假如有两个logfile文件,第一个写满后会写第二个,第二个写满后会重新覆盖第一个,这时候如果第一个logfile中对应的脏块还没有写完,就会先将脏块写入到磁盘之中再覆盖,首先要将较早脏的数据块写入到磁盘之中,这时候就会有问题,系统怎么知道哪个是free数据块,那些是冷数据块,那些是较早脏的快。这时候就引入了free list,lru list,flush list。

mysql中用链的形式把数据块穿起来。

  • freelist就能够free块穿起来,当寻找free块时,就按照某种顺序来将新来的数据写入到free数据块中。
  • lru list就是将冷数据块连接起来,按照某种顺序将新来的数据覆盖上去
  • flush list原理相同,通过链把脏数据按照某种顺序(比如最早脏的在最左边)将脏数据连接起来,方便写入。

锁,用来管理对共享文件的并发访问

锁的类型

  • latch称为栓锁(轻量级的锁),因为其要求锁的时间非常短。
  • 在innodb存储引擎中,又可以分为mutex(互斥量)和rwlock(读写锁)。其目的是用来保证并发线程操作临街资源的正确性,并且通常没有死锁检测的机制
  • lock锁的对象是事务,用来锁定数据库的对象,如表、页、行。并且一般lock的对象仅在事务commit或者rollback后释放(不同事务的隔离级别释放的时间可能不一样)。有死锁机制

链上是有锁的。latch 锁。
例子:
线程1持有latch,对free list正在进行遍历;
线程2也想持有latch,对free list进行遍历;
结果,线程2被阻塞。

线程的三种状态

  • gets:获取latch
  • misses:获取latch失败了
  • sleeps:执行空代码,显得很忙。

都伴随着latch的征用。

latch争用的表现

  • 1.latch争用会表现为cpu繁忙;
  • 2.latch争用没有排队。

latch(锁)争用的原因

  • 1.内存访问频繁;
  • 2.list 太长了。

latch争用的过程

首先链上是有锁的,这个锁叫latch,当一个线程持有latch时(也就是对这个链进行操作的时候),其他的线程得在一边看着。比如线程1持有latch,正在对freelist进行遍历,线程2也想进行遍历,是不可能的,所以现在线程2阻塞,只有两种选择,一是退出,二是等待,但如果等待就会占用cpu,如果想占用cpu就要有事可做,否则cpu会把没事做的线程踢出去,所以线程2就会执行某段空代码来让自己忙起来(所以虽然线程2在等待,但cpu还是忙碌的),这时候线程2会有三种情况:gets,misses,sleeps。gets就是随机的去看看freelist是否已经可以遍历,misses就是线程2错过了freelist可遍历时间,被线程3抢走了,只能重新等待,sleeps就是misses的太多了,受不了了,不执行空代码乖乖的退出了。

  • latch争用过程中,会表现的cpu繁忙
  • latch争用没有排队
  • latch争用比较严重时,要调整innodb_buffer_pool中instance的数量,
  • instance数量多了,每个instance中数据就少了,链也就短了。
  • latch争用繁忙时,内存被频繁的访问,因为链在内存之中。
  • 对于访问不是很频繁,同时相对较短的链,用mutex来保护而不用latch,因为mutex更为简单,占用空间小。

latch争用常用监控指标

RW-shared spins 0, rounds 16, OS waits 8
RW-excl spins 0, rounds 0, OS waits 0
RW-sx spins 0, rounds 0, OS waits 0
Spin rounds per wait:16.00 RW-shared, 0.00 RW-excl, 0.00 RW-sx

这几个数据是看latch与mutex的争用成都如果过高
需要优化mysql,降低对内存读的数量(很重要)。

mutex 互斥锁

操作系统的mutex 的特点:

  • 小;通过os申请,不占用自己的内存。
mysql>show engine innodb status \G
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 2, signal count 2
Mutex spin waits 0, rounds 0, OS waits 0
RW-shared spins 2, rounds 60, OS waits 2
RW-excl spins 0, rounds 0, OS waits 0
Spin rounds per wait: 0.00 mutex, 30.00 RW-shared, 0.00 RW-excl
--------
  • oswaits:sleep的时间
  • innodb在获得mutex时是两阶段的。如果Mutex被人锁住了,那么它不会像教科书里面的那样,直接就sleep等待被唤醒了。而是先做一个循环,不断去获得mutex锁,称之为spin-wait,然后才sleep。因为sleep等待被唤醒的代价还是比较高的。通过spin-wait,可以明显降低这个开销。
  • mutex spin waits 这个代表的是线程获得的锁,但是被别人锁住了,所以它得首先spin-wait;
  • rounds:是线程在spin-wait循环检查mutex是否已经释放的探测次数;
  • OS waits:是spin-wait完成以后,还是没有获得mutex,不得不sleep的次数。这个主要是评估mutex获取不到的比例。比如:
    • 请求mutex不到的情况是 mutex spin waits的数,但是经过spin-wait,实际上只有OS waits的次数,也就是说,中间的差值,就是稍微等一下就能拿到mutex。

mutex:排斥。
spin:旋转。
rounds:旋转一周是1round;
os waits:就是sleep,被踢出去了;
第二行是:以共享的形式访问的时候的统计;
第三行是:以排他的形式访问的时候的统计。

如何降低latch争用

  • 对访问不是很频繁,同时相对较短的链,我们使用mutex就可以来保护这些链。
  • 所以,对于访问频繁的链,(会有大量的读和写),还是要用latch来进行保护。
  • mutex可以理解为排他的latch。
  • mutex只能写编号。

解决方案:

  • 1.优化SQL,降低对内存读的数量;
  • 2.增加instances的数量。

关于LRU链表

Innodb存储引擎对传统的LRU(Least Recently Used 最近最少使用)算法做了优化,LRU列表中加入了midpoint位置。新读取到的页,虽然是最新访问的页,但并不是直接放入到LRU列表的首部,而是放入到LRU列表的midpoint位置。

这个算法在InnoDB存储引擎下称为 midpoint inserttion strategy。在默认配置下,该位置在LRU列表长度的5/8处。
midpoint位置可由参数 innodb_old_blocks_pct 控制,eg:

mysql>show variables like 'innodb_old_blocks_pct'\G;

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯言甚善

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值