快速掌握 Innodb:从解析 show engine innodb shatus 开始

快速掌握 Innodb:从解析 show engine innodb shatus 开始_第1张图片

一、前言

MySQL 最早由瑞典 MySQL AB 公司开发,该公司由 Monty 在 1995 年创立;MySQL 这个名字来源于 Monty 的大女儿 My。它的成功不仅仅是因为免费,还有它的可靠性稳定性和一些其它闪亮的特性。而 MySQL 中最核心的组建就是存储引擎,令人意外的是 Innodb 引擎的发展进程竟然比 MySQL 要早,甚至在时间上远远甩开了一些高级编程语言

值得一提的是,MySQL 和 linux 两大开发源码的阵营都出自芬兰人之手,按照采访 Monty 时他的说法,芬兰人的本性就是固执和讨厌放弃,截止现在 Linus 在 Linux 方面坚持了 30 年,而 Monty 也坚持了 20 年,他们的这种专注和坚持是值得我们学习的。

理解 Innodb 的第一步就是要熟悉 show engine innodb shatus 中输出结果的含义,今天我们一起来学习它。

二、环境及输出

  • 操作环境:MySQL 5.7.28
  • 输出结果:show engine innodb status\G
  • 上面就是输出结果,主要包含一些 innodb 引擎中的一些状态,共有 10 个部分
  1. BACKGROUND THREAD:后台 Master 线程状态
  2. SEMAPHORES:等待线程的列表及事件计数器,评估当前负载情况
  3. LATEST DETECTED DEADLOCK:最新的几次死锁信息数据(只有发送死锁时显示)
  4. latest foreign key error:最近几次外键错误信息(只有发生错误时显示)
  5. TRANSACTIONS:innodb 事务统计信息
  6. FILE I/O:显示的是I/O辅助线程的状态及性能计数器的状态
  7. INSERT BUFFER AND ADAPTIVE HASH INDEX:insert buffer pool 和 AHI 状态
  8. LOG:innodb 事务日志 Redo 的统计信息
  9. BUFFER POOL AND MEMORY:innodb buffer pool 使用统计信息
  10. ROW OPERATIONS:ROW 操作和其它统计信息

三、内容解析

快速掌握 Innodb:从解析 show engine innodb shatus 开始_第2张图片
show engine innodb status 显示的不是当前实时的状态,而是过去某个时间范围的状态,上图为输出的时间信息表示:查询信息为过去的 21 秒内,每两秒内平均值

快速掌握 Innodb:从解析 show engine innodb shatus 开始_第3张图片
介绍:Master 线程三种状态

  • Master 线程是 innodb 引擎中最重要的线程,主要负责异步刷新数据维护数据一致性处理,有三种工作状态,每次循环都会根据数据库状态选择其中一种工作状态。
  • Active 是 Master 线程判断系统处于忙碌状态时选择的工作模式,它的循环数量增加主要与数据变化有关,与查询无关。
  • Idle是 Master 线程判断系统处于空闲状态选择的工作模式,Idle 与 Active 两种工作模式做的事情几乎都一样,只不过执行时间间隔不同。
  • shutdown 是在关闭实例时才会选择的工作模式。

解析:输出解析

  • 上图是一台比较空闲实例运行的结果,可以看到 srv_active 为 567 而 srv_idle 则为 1756519 远远大于 active 循环次数,所以可以对比两 active 和 idle 的值来判断系统的负载情况。
  • 相对的如果实例输出的结果 srv_idle 远远大与 active 则可以认为系统处于忙碌状态

快速掌握 Innodb:从解析 show engine innodb shatus 开始_第4张图片

  • FILE I/O 主要是关于 innodb 中 IO Thread 线程的相关信息。
  • IO Thread 线程分别为:Read threadWrite threadInsert buffer threadLog thread 使用的是异步 I/O 模型,处理不同类型的 I/O 请求和回调。
  • 可以通过上图信息清晰看到 IO Thread 的信息,其中 read threadwrite thread线程分别4 个,Log thread 和 insert buffer thread 线程分别各一个,其中 read 和 write 线程可以根据参数来调整。

快速掌握 Innodb:从解析 show engine innodb shatus 开始_第5张图片
BUFFER POOL AND MEMORY 主要是关于 Innodb 的缓存池管理相关数据

  • Total large memory allocated:innodb 分配的总内存 (byte)
  • Dictionary memory allocated:innodb数据字典分配的内存数(byte)
  • Buffer pool size:缓冲池分配的页数
  • Free buffers:缓冲池空闲页数
  • Database pages:LRU 列表中分配的数据页(LRU 是 innodb 管理缓存的算法)
  • Old database pages:LRU 在 old sublist部分页的数量
  • Modified db pages:buffer pool 中的数据脏页
  • Pending reads:挂起读的数量

LRU 算法介绍:数据库缓存技术中都会使用的算法

  • 算法思想:LRU 的本质是让数据页在缓存中长时间保留,提高查询访问效率,但是缓存是有限的,LRU 的作用就是减少重复数据页加载频率
  • 算法解析:LRU 是 innodb 中的一种定制化算法,首先它会有一个列表,叫 LRU LIST 上面存放一些数据页,这个列表就是 Database pages 上图是 6885 个数据页 大约 1MB innodb 在 LRU 列表中加入了参考点,叫midpoint 当访问到的数据页不在缓冲区会直接将磁盘中的数据页调到缓冲区队列;innodb 不是将数据页直接插入到缓冲区队列队头,而是插入 LRU 列表的 midpoint 位置。默认配置 midpoint 是在整个列表长度的5/8 处,和数学中的黄金分割 0.618 很接近,midpoint 是由innodb_old_blocks_pct控制。LRU LIST在 midpoint 之前的列表称为 young sublist 或者sublist of new block 里面的数据是热数据,而LRU LISTmidpoint之后的列表称为 old sublist或者sublist of old block
    快速掌握 Innodb:从解析 show engine innodb shatus 开始_第6张图片
  • 算法过程:当缓冲池不能存放新读取到的页时,将首先释放 LRU 列表中尾端的页。当一些全表扫描如果进入 sublist of new block 区域,整个 LRU 就会是性能瓶颈,这种情况叫缓存污染。为了解决这种问题,innodb 加入了 innodb_old_blocks_time 来表示数据页读取到 mid 位置后需要等待多久才会进入 LRU 列表的热端,默认为1000 毫秒,可以设置此参数保证热点数据不会被轻易刷出。

快速掌握 Innodb:从解析 show engine innodb shatus 开始_第7张图片
Innodb 引擎日志管理

  • 上图主要展示的是关于 innodb 日志相关,所以我们需要了解 innodb 引擎中日志的作用,主要有两种类型的日志 redo log 重做日志和 undo log 回滚日志,分别存储在 ib_logfile 和 ibdata 文件中
  • LSN 介绍:redo 日志的作用是为了维护事务的持久性故障自动恢复,都会基于 LSN 日志序列号,LSN 是一个一直递增的整型数字(8 个字节),表示事务写入到日志的字节总量,每个数据页和重做日志及 checkpoint 都有 LSN。
  • checkpoint:innodb 的刷盘机制,可以将 buffer pool 中的数据脏页刷写到磁盘
  • redo 日志工作机制:上面已经提过 redo 日志主要维护事务的持久化存储,我们现在认识 LSNcheckpoint 后仔细讨论,当执行一条 DML 语句时 innodb 会将硬盘中需要改动的数据页加载到 buffer pool 正常逻辑是在内存中修改完成后再刷到磁盘中,但是这样有风险如果此时宕机 buffer pool 中没有刷写到到数据就会失效,所以 innodb 会先将改动数据记录加载到 redo buffer pool 中然后再由它快速刷写到 redo 的物理存储空间中,此时如果宕机那么原数据+改动数据记录就可以恢复宕机前的状态,这个恢复过程就是故障自动恢复机制,MySQL 在启动时会对比数据和 ib_logfile 中到 LSN 编号,如果不一样则认为数据不一致,启动自动故障恢复机制恢复数据后才会启动成功。
  • undo 日志工作机制:undo 日志主要维护的事务的原子性,事务执行过程会将事务的反操作记录到 undo物理空间中,默认在 ibdata 共享文件中,但是 ibdata 太过庞大 5.7 版本后可以通过 innodb_undo_tablespaces 指定需要匹配几个 undo 文件。

LOG 数据解析:

  • Log sequence number:LSN1 当前系统 LSN 最大值,新的事务日志将在原日志基础上生成(LSN1 + 新日志的大小)
  • Log flushed up to:LSN2 当前已经写入日志文件的 LSN
  • Pages flushed up to:LSN3 当前最旧的数据脏页对应的 LSN 执行 checkpoint 时可以直接将此 LSN 写入到日志文件。
  • Last checkpoint at:LSN4 当前已经被 checkpoint 写入的 LSN

快速掌握 Innodb:从解析 show engine innodb shatus 开始_第8张图片

  • 主要是等待线程的列表及事件计数器和一些的情况,可以评估系统的负载情况
  • 目前这部分相对来说用的比较少,网络上的资料比较模糊,详细描述后补。

快速掌握 Innodb:从解析 show engine innodb shatus 开始_第9张图片

  • 死锁一般是事务相互等待对方资源,最后形成环路造成的。出现死锁 MySQL 也会检测到,然后通过回滚事务解决。发生死锁会增加系统负担,MySQL 错误日志也会记录死锁问题,查询到根源然后解决和避免死锁问题。当然也可以通过上图发现和结果最近的几次死锁问题。除了死锁系统还有外键错误记录。

三、总结

  • 上面我们介绍 innodb 体系结构中比较重要的指标,从show engine innodb shatus 的结果就可以看出 innodb 引擎的一个大体结构,四个线程、buffer pool、redo 和 undo、锁机制和相关特性,当然这只是冰山一角,要想真正理解 innodb 还需要多花点时间

你可能感兴趣的:(MySQL,mysql)