Innodb结构

2023-11-15

从MySQL5.5版本开始默认使用InnoDB作为引擎,它擅长处理事务,具有自动崩满恢复的特性,在日常开发中使用非常广泛,下面是言方的InnoDB引擎美构图,主要分为内存结构和磁盘结构两大部分。 

 内存结构主要包括Buffer Pool、Change Buffer、Adaptive Hash Index和Log Buffer四大组件。
Buffer Pool:缓冲池,简称BP。BP以Page页为单位,默认大小16K,BP的底层采用链表数据结构管理Page。在InnoDB访问表记录和索引时会在Page页中缓存,以后使用可以减少磁盘IO操作,提升效率。

缓冲池简单来说就是一块内存区域,通过内存的速度来弥补磁盘速度较慢对数据库性能的影响。在数据库中进行读取页的操作,首先将从磁盘读到的页存放在缓冲池中,这个过程称为将页"FIX"在缓冲池中。下一次再读取相同的页时,首先判断该页是否在缓冲池中。若在缓冲池中,称该页在缓冲池中被命中。直接读取该页。否则读取磁盘上的页。对于数据库中页的修改操作,则首先修改在缓冲池中的页,然后再以一定的频率刷新到磁盘上。这里需要注意的是,页从缓冲池刷新回磁盘的操作并不是每次页发生更新时触发,而是通过一种称为Checkpoint的机制刷新回磁盘。同样这也是为了提高数据库的整体性能。

对于innodb存储引擎而言,其缓冲池的配置通过参数innodb_buffer_ pool_size来设置。这是影响innodb性能的关键参数。具体来看,缓冲池中缓存的数据页类型有:索引页,数据页,undo页,插入缓冲(insert buffer),自适应哈希索引(adaptive hash index),innodb存储的锁信息(lock info),数据字典信息(data dictionary)等。不能简单的认为,缓冲池只是缓存索引页和数据页,它们只是占缓冲池很大的一部分而已。

Page管理机制
  Page根据状态可以分为三种类型:
     ·free page:空闲page,未被使用
     ·clean page:被使用page,数据没有被修改过
     ·dirty page:脏页,被使用page,数据被修改过,页中数据和磁盘的数据产生了不一致

针对上述三种page类型,InnoDB通过三种链表结构来维护和管理
    ·free list:表示空闲缓冲区,管理free page
    ·flush list:表示需要刷新到磁盘的缓冲区,管理dirty page,内部page按修改时间排序。脏页即                       存在你flush链表,也在LRU链表中,但是两种互不影响,LRU链表负责管理page的                         可用性和释放,而flush链表负责管理脏页的刷盘操作。
    ·Iru list:表示正在使用的缓冲区,管理clean page和dirty page,缓冲区以midpoint为基点,前                      面链表称为new列表区,存放经常访问的数据,占63%;后面的链表称为old列表区,                      存放使用较少数据,占37%。
改进型LRU算法维护
    普通LRU:未尾淘汰法,新数据从链表头部加入,释放空间时从未尾淘汰
    改性LRU:链表分为new和old两个部分,加入元素时并不是从表头插入,而是从中间midpoint                         位置插入,如果数据很快被访问,那么page就会向new列表头部移动,如果数据没                         有被访问,会逐步向old尾部移动,等待淘汰。

                     每当有新的page数据读取到buffer pool时,InnoDb引擎会判断是否有空闲页,是否                         足够,如果有就将free page从free list列表删除,放入到LRU列表中。没有空闲页,                        就会根据LRU算法淘汰LRU链表默认的页,将内存空间释放分配给新的页。

BUffer pool配置参数:

show variables like%innodb_page_size%;/查看page页大小

show variables like 9%innodb_old%;//查看ru list中old列表参数

show variables like9%innodb_buffer%;//查看buffer pool参数

建议:将innodb_buffer_pool_size设置为总内存的60%-80%,innodb_buffer_pool_instances可以设置为多个,这样可以避免缓存争夺。|

从innodb1.0.x版本开始,允许有多个缓冲池实例。每个页根据哈希值平均分配到不同缓冲池实例中。这样做的好处是减少数据库内部的资源竞争。增加数据库的并发处理能力。通过参数innodb_buffer_pool_instances来进行配置。该值默认为1。在配置文件中将innodb_buffer_pool_instances设置为大于1的值就可以得到多个缓冲池实例。

注意:innodb_buffer_pool_size必须大于1GB,生成innodb_buffer_pool多实例才有效,最多支持64个innodb_buffer_pool实例。

 Change Buffer:写缓冲区,简称CB。在进行DML操作时,如果BP没有其相应的Page数据,并不会立刻将磁盘页加载到缓冲池,而是在CB记录缓冲变更,等未来数据被读取时,再将数据合并恢复到BP中。
ChangeBuffer占用BufferPool空间,默认占25%,最大允许占50%,可以根据读写业务量来进行调整。
参数innodb_change_buffer_max size;当更新一条记录时,该记录在BufferPool存在,直接在BufferPool修改,一次内存操作。如果该记录在BufferPool不存在(没有命中),会直接在ChangeBuffer进行一次内存操作,不用再去磁盘查询数据,避免一次磁盘1O。当下次查询记录时,会先进性磁盘读取,然后再从ChangeBuffer中读取信息合并,最终载入BufferPool中。
写缓冲区,仅适用于非准一普通索引页,为什么?
如果在索引设置唯一性,在进行修改时,InnoDB必须要做唯一性校验,因此必须查询磁盘,做一次I0操作。会直接将记录查询到BufferPool中,然后在缓冲池修改,不会在ChangeBufer操作。

Adaptive Hash Index:自适应哈希索引,用于优化对BP数据的查询。InnoDB存储引擎会监控对表索引的查找,如果观察到建立哈希索引可以带来速度的提升,则建立哈希索引,所以称之为自适应。InnoDB存储引擎会自动根据访问的频率和模式来为某些页建立哈希索引。
Log Bufer:日志缓冲区,用来保存要写入磁盘上log文件(Redo/Undo)的数据,日志缓冲区的内容定期刷新到磁盘log文件中。日志缓冲区满时会自动将其刷新到磁盘,当遇到BLOB或多行更新的大事务操作时,增加日志缓冲区可以节省磁盘/O。
LogBuffer主要是用于记录InnoDB引擎日志,在DML操作时会产生Redo和Undo日志。
LogBuffer空间满了,会自动写入磁盘。
innodb_flush_log at trxrcommit参数控制日志刷新行为,默认为1
  0:每隔1秒写日志文件和刷盘操作(写日志文件LogBuffer->oS cache,刷盘OS cache->磁盘文          件),最多丢失1秒数据
 1:事务提交,立刻写日志文件和刷盘,数据不丢失,但是会频繁10操作
 2:事务提交,立刻写日志文件,每隔1秒钟进行刷盘操伸

从上图大致可以看到innodb有多个内存块,可以认为这些内存块组成了一个大的内存池,负责如下工作:

1.维护所有进程/线程需要访问的多个内部数据结构。

2.缓存磁盘上的数据,方便快速的读取,同时在对磁盘文件的数据修改之前在这里缓存。

3.重做日志(redo log)缓冲

一.后台线程的主要作用是负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最新最近的数据。此外将已经修改的数据文件刷新到磁盘文件,同时保证在数据库发生异常的情况下innodb能恢复正常的运行状态。

后台线程:

Innodb存储引擎是多线程的模型,因此其后台有多个不同的后台线程,负责处理不同的任务。

1.Master Thread

Master Thread 是非常核心的后台线程,主要负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性,包括脏页的刷新,合并插入缓冲(insert buffer),undo页的回收等。

2.IO Thread

在innodb存储引擎中大量使用了AIO(Async IO)来处理写IO请求,这样可以极大提高数据库的性能。而IO Thread的工作主要负责这些IO请求的回调(call back)处理。在innodb 1.0版本之前共有4个IO Thread,分别是write,read,insert buffer和log IO thread。从innodb 1.0.x版本开始,read thread和write thread分别增大到了4个。可以使用innodb_read_io_threads和innodb_write_io_threads参数进行设置。

3. Purge Thread

事务被提交后,其使用的undo log可能不再需要,因此Purge Thread来回收已经使用并分配的undo页。在innodb 1.1 版本之前,purge操作仅在innodb存储引擎的Master Thread中完成。从innodb1.1版本开始,purge操作可以独立到单独的线程中进行。以此来减轻Master Thread的工作。从而提高CPU的使用率以及提升存储引擎的性能。可以通过在配置文件中添加如下参数来开启独立的Purge Thread(清洗线程)

 在innodb1.1版本中,即使innodb_purge_threads设为大于1,innodb存储引擎启动时也会将其设为1,从innodb1.2版本开始,innodb支持多个Purge Thread,这样做的目的是为了进一步加快undo页的回收。同时由于Purge Thread需要离散的读取undo页,这样可以更好的利用磁盘的随机读取性能。

4.Page cleaner Thread

page cleaner thread线程是在innodb 1.2.x的版本中引入的。其作用是将之前的版本中的脏页刷新操作都放入到单独的线程中来完成。而其目的是为了减轻原Master Thread的工作及对于用户查询线程的阻塞,进一步提高innodb存储引擎的性能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Innodb结构 的相关文章

  • ORDER BY id 或 date_created 显示最新结果?

    我有一个表 实际上有几个 我想首先从中获取最新条目的结果 这是我的ORDER BY条款选项 date created INT 从不改变值 id 当然是INT AUTO INCRMENT 两列应同等地代表记录插入的顺序 我自然会使用date
  • 使用 RMySQL 会干扰 RPostgreSQL

    我有一个 R 脚本 我想从 MySQL 数据库中提取一些数据 然后从 PostgreSQL 数据库中提取一些数据 但是 从 RMySQL 加载 MySQL 驱动程序会阻止我从以下位置加载 PostgreSQL 驱动程序 PostgreSQL
  • mysqli_stmt_bind_result 的奇怪问题

    好吧 这让我很烦恼 我似乎在 PHP 文档中找不到任何内容 在 Google resultosphere 中也找不到任何内容 所以也许有人可以在这里提供帮助 我正在使用准备好的语句 绑定结果 然后使用这些绑定结果来填充下拉列表 例子
  • mysql计算唯一行值

    TABLE quotation id clientid 1 25 2 25 3 25 4 25 5 26 如何查询有多少个不同的客户端TABLE quotation 我不希望重复的条目被计算多次 我需要的答案是2 在 1 行中 因为唯一的非
  • 是否可以在MYSQL中动态选择列名,其中列名是N个已知值中的1?

    我担心答案会是直接的 不 但我想知道是否可以在 MySQL 中执行如下操作 SELECT title label name FROM table 即选择单个列 可以称为title label or name from table 原因是 查
  • mysql jdbc 与 SSL 连接在 tls 握手级别失败

    我们的 mysql 服务器配置为仅接受与 ssl 密码 DHE RSA AES256 GCM SHA384 的连接 我正在使用 java mysql connector java 8 0 15 和 java 8 openjdk 版本 1 8
  • 使用 cfchart 标签在单个饼图中显示多个查询的数据

    请考虑以下代码 现在我的代码中有以下代码 cfm页面内的 tag DataSource xx xx x xx Name of the database sgemail Name of the relevant column event vc
  • mysql 在 sum() 函数上使用 concat,例如 concat(sum(col1),"%")

    我正在尝试合并多个查询 但其中一个查询使用 sum 当我尝试在此列上应用 concat 时 我得到不需要的 blob 结果 我如何在聚合列上应用 concat 和 union 我期待这个结果 SELECT row 1 col1 UNION
  • 如何使用MySqlCommand和prepare语句进行多行插入?(#C)

    Mysql 给出了如何使用准备语句和 NET 插入行的示例 http dev mysql com doc refman 5 5 en connector net programming prepared html http dev mysq
  • #1115 - 未知字符集:'utf8mb4'

    我的电脑上运行着一个本地网络服务器 用于本地开发 我现在正处于导出数据库并导入到我的托管 VPS 的阶段 导出然后导入时出现以下错误 1115 未知字符集 utf8mb4 有人能指出我正确的方向吗 该错误明确表明您没有utf8mb4您的阶段
  • INNER JOIN 后从多个表获取最大日期

    我有以下两个表 table 1 ID HOTEL ID NAME 1 100 xyz 2 101 pqr 3 102 abc table 2 ID BOOKING ID DEPARTURE DATE AMOUNT 1 1 2013 04 1
  • 无法在 Laravel 8 中运行迁移:SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: 名称或服务未知 [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我不明白为什么我的迁移在全新安装 Laravel 8 时失败 这就是我得到的结果 Illuminate Database
  • MySQL Workbench 忽略外键

    在处理 MySQL Workbench 中的 SQL 编辑器时 我偶然发现了一些奇怪的事情 其中 执行似乎忽略了外键约束 这是一个例子 create database testdb use testdb create table t1 te
  • Laravel:使用 Faker 播种多个独特的列

    介绍 怎么样 伙计们 我有一个关于模型工厂和多个独特列的问题 背景 我有一个名为 Image 的模型 该模型将语言支持存储在单独的模型中 图片文字 图片文字 has an image id栏 语言栏和文本栏 图片文字有一个约束MySQL那个
  • 数据库级别的别名列名 [MySQL]

    别名 可能是错误的词 因为它是在将列 表名称作为查询中的其他名称引用的上下文中使用的 我感兴趣的是是否有一种方法可以在数据库中为列指定两个名称 如果我要打印这样的表格 它看起来会是这样的 mysql gt SELECT FROM User
  • Python 的 mysqldb 晦涩文档

    Python 模块 mysqldb 中有许多转义函数 我不理解它们的文档 而且我努力查找它们也没有发现任何结果 gt gt gt print mysql escape doc escape obj dict escape any speci
  • Laravel Schema Builder 改变存储引擎

    我正在尝试更改表并将其存储引擎更改为InnoDb 当我跑步时php artisan migrate它完成且没有错误 然而 当我检查 Sequel Pro 中的存储引擎时 没有任何变化 public function up Schema ta
  • MySQL 复制是双向的

    我们已经成功设置了 MySQL 文献中描述的主从复制 不过 我很好奇是否有人设置了双向复制 例如 如果安装了 Drupal 或 Wordpress 第一个 主 数据库服务器出现故障 第二个 从属 数据库服务器恢复正常 与此同时 用户不断进行
  • 更新 SQLAlchemy 中的特定行

    我将 SQLAlchemy 与 python 一起使用 我想更新表中等于此查询的特定行 UPDATE User SET name user WHERE id 3 我通过 sql alchemy 编写了这段代码 但它不起作用 session
  • mysql 数据库正在复制,但在主服务器上创建的用户未在从服务器上复制

    在主从复制中 我们使用 mysql DB 在从服务器上复制少量数据库 我在主服务器上创建了一个用户 不幸的是它没有在从服务器上复制 Replicate Do DB app1 app2 mysql 用户创建命令 GRANT SELECT on

随机推荐

  • Python中装饰器超详细讲解,看不懂尽管来砍我!

    Python中装饰器的那些事儿 说到装饰器 我们需要首先理解下闭包的概念 走起 定义 具有执行环境的函数 满足三个条件 1 外部函数中定义一个内部函数 2 内部函数中使用外部函数的局部变量 3 外部函数将内部函数作为返回值返回 此时的内部函
  • 算法:2-3平衡树与B树的详细探讨

    2 3树是最简单的B树 B 树是B树的升级 B树的来源 为什么要有树 描述 1 多 N M 层次等关系 从最根本的原因来看 使用树结构是为了提升整体的效率 插入 删除 查找 索引 尤其是索引操作 因为相比于链表 一个平衡树的索引时间复杂度是
  • js关闭当前弹出框,刷新父页面

    alert data msg 点击确定关闭该窗口 reload 关闭当前窗口 刷新上一层页面 location reload 执行结束 刷新当前页面 父级页面 点击操作按钮 点击保存 点击确定可以看到已经回到上一级页面 且已刷新
  • Java 线程同步 - 7种方式

    为何要使用同步 java允许多线程并发控制 当多个线程同时操作一个可共享的资源变量时 如数据的增删改查 将会导致数据不准确 相互之间产生冲突 因此加入同步锁以避免在该线程没有完成操作之前 被其他线程的调用 从而保证了该变量的唯一性和准确性
  • 3分钟学习:获取 URL 查询参数值

    在前端开发工作中 利用 URL 进行参数传递是一项十分常见的方法 在页面跳转时 通过 URL 携带某些信息 如状态 id 区分页面来源的字段值等 因此 学习了解如何获取 URL 查询参数值是很重要的 js 代码手撸 利用 JavaScrip
  • 使用sessionStorage新建与本页面一样的Tab页面,并在页间传递参数。

    客户提了个需求 点击某个链接 新建一个Tab页 当前页面内容不变 新的Tab页中控件的值和当前页一致 查阅了相关博客 发现可以用sessionStorage或者localStorage实现 键值对属性的存储 获取 Demo实现思路 页面加载
  • TCP/IP UDP 协议首部及数据进入协议栈封装的过程

    数据的封装 UDP 封装 TCP 封装 IP 封装 检验和算法 当应用程序用TCP传送数据时 数据被传送入协议栈中 然后逐一通过每一层直到被当作一串比特流送入网络 注 UDP数据TCP数据基本一致 唯一不同的是UDP传给IP的信息单元称作U
  • 【详解python中round函数】

    在Python中 round 函数是一个内置函数 用于将一个数字四舍五入为指定的小数位数或整数位数 round 函数有两个参数 第一个参数是要四舍五入的数字 第二个参数 可选 是小数位数或整数位数 表示要保留的小数位数或整数位数 默认为0
  • iOS 审核被拒绝3.2.1 没有金融许可证

    今年金融行业不好做 p2p暴雷好多家 上半年Android应用市场整顿金融类应用 在华为应用市场被误认为p2p应用而下架 经过上诉上传资质证明得而重新上架 各个应用商店平台陆续需要资质证明 最近应用在苹果商店审核被拒绝 同样也是因为金融类资
  • Redirecting to /bin/systemctl stop iptables.service Failed to stop iptables.service: Unit iptables.s

    学习远程访问mysql时 由于centos的防火墙会自动屏蔽很多软件的端口 所以无法连接 于是要关闭防火墙 网上找方法后知道输入 service iptables stop可以关闭防火墙 但是没有成功 因为centos7不能关闭防火墙 所以
  • 这真是冷门又逆天的副业,赚的有点多,分享一下接单心得

    前言 每年春节前后 都会是Python兼职接单的小高潮 这段时间各个行业对爬虫类和数分类的需求会暴增 圈子里很多朋友双休都没闲着 两天赚上万的不在少数 最近发现技术变现 兼职接单问题很多 我总结下来 发现大部分人都有着相同的困惑 听说Pyt
  • CSS鼠标滑过翻转动画图标

    html css鼠标放上去变大效果 效果如下动态图 目录层级 代码如下 html文件 index html li li
  • 图片存在灰白、深黑区域的检测

    import cv2 as cv file path E Python pythonProject 4 1 jpg def blackAndwhite screen file path img cv imread file path row
  • python 解决 pip 时报错 no suchoption: --bulid-dir 的解决办法

    python m pip install pip 20 2 4
  • Struts2 commons-fileupload 在上传2M以上文件出现异常解决方法

    在上传2M以上文件出现异常如下 APPNAME ERROR http 80 3 MultiPartRequest parse 130 org apache commons fileupload FileUploadBase SizeLimi
  • FISCO BCOS 区块链

    FISCO BCOS是由国内企业主导研发 对外开源 安全可控的企业级金融联盟链底层平台 由金链盟开源工作组协作打造 并于2017年正式对外开源 社区以开源链接多方 截止2020年5月 汇聚了超1000家企业及机构 逾万名社区成员参与共建共治
  • 泛型是什么,C++泛型编程又是什么?

    泛型是什么 C 泛型编程又是什么 在计算机程序设计领域 为了避免因数据类型的不同 而被迫重复编写大量相同业务逻辑的代码 人们发展的泛型及泛型编程技术 什么是泛型呢 所以泛型 实质上就是不使用具体数据类型 例如 int double floa
  • 高效率同步4开关Buck-Boost DC/DC控制器TMI5700

    随着户外储能电源应用需求的增加 以及PD大功率车充产品的广泛推广 应对不同输入供电设备 如5V 19V的适配器 以及12V 24V车载充电器 或电池组 4 2V 17 6V 都需要转换成5 20V的PD电压来应对不同负载设备的供电需求 图1
  • 基于R的飞机航线数据可视化(卫星地图)

    基于R的飞机航线数据可视化 卫星地图 数据处理 加载库 加载地图 说明 上一篇是基于行政区划进行可视化 本篇是基于卫星地图进行可视化 上一篇指路 基于R的飞机航线数据可视化 行政区划 数据处理 基础数据的处理与上一篇相同 不做解释 加载库
  • Innodb结构

    从MySQL5 5版本开始默认使用InnoDB作为引擎 它擅长处理事务 具有自动崩满恢复的特性 在日常开发中使用非常广泛 下面是言方的InnoDB引擎美构图 主要分为内存结构和磁盘结构两大部分 内存结构主要包括Buffer Pool Cha