iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >Mysql InnoDB 的内存结构详情
  • 222
分享到

Mysql InnoDB 的内存结构详情

2024-04-02 19:04:59 222人浏览 安东尼
摘要

目录1 前言2 InnoDB 存储引擎结构2.1 InnoDB表存储引擎文件2.2 InnoDB 预读机制2.3 InnoDB 特性2.3.1 插入缓存2.3.2 二次写 

1 前言

我们都熟悉Mysql数据库服务架构,也清楚 sql 的执行顺序,mysql的数据在磁盘和内存中的存储结构是采用B+树的数据结构,但是在InnoDB引擎中,数据在内存和磁盘中的展示形式以及怎么和mysql的服务架构建立联系,sql 查询和 InnoDB 引擎之前的联系,可能就不是不清楚了。

mysql 的逻辑架构图如下所示: 

2 InnoDB 存储引擎结构

InnoDB存储引擎的逻辑存储结构是什么呢,其实所有的数据都被逻辑地放在了一个空间中这个空间中的文件就是实际存在的物理文件,即表空间。默认情况下,一个数据库表占用一个表空间,表空间中存放该表对应的数据、索引、insert buffer bitmap undo信息、insert buffer 索引页、double write buffer 等是放在共享表空间中的。

# 默认一个数据库表单独占有一个表空间
show variables like '%innodb_file_per_table%'
innodb_file_per_table=ON
# 修改设置
SET GLOBAL innodb_file_per_table=OFF; 

2.1 InnoDB表存储引擎文件

 每个表空间由 段 segment 区 extent 页 page 组成。页是数据存储数据的基本单位,默认大小为 16kb。 区是由连续页组成的空间,默认大小为 1MB。多个区构成表的段。 InnoDB 逻辑存储结构 

在我们执行sql时,不论是查询还是修改,myql 总会把数据从磁盘读取内内存中,而且在读取数据时,不会单独加在一条数据,而是直接加载数据所在的数据页到内存中,而读取的方式有两种,现行预读方式和随机预读方式,默认采用线性预读方式。

InnoDB 引擎架构 :

2.2 InnoDB 预读机制

线性预读和随机预读:

线性预读是以 extent 为单位,而随机预读是以 extent 中的page 为单位,线性预读着眼于将下一个extent 数据读取到 buffer pool 中,而随机预读是将当前extent中剩余的page读到 buffer pool 中。 如果一个extent 区中被顺序读取得page数量超过一定的数量( innodb_read_ahead_threshold),则直接加载 extent 中剩余的数据页。

2.3 InnoDB 特性

2.3.1 插入缓存

插入缓冲(Insert Buffer/Change Buffer)为了提升插入性能,insert buffer 是 insert buffer 的增强版,insert buffer 只对插入有效,而change buffer对 insert/update/delete 都有效。插入缓存只对非唯一索引和辅助索引有效,对每一次的插入不是写到索引页中,而是先判断插入的非聚集索引页是否在缓存中,如果在则直接插入,不存在则插入到 insert buffer 中,按照一定的频率进行合并操作,写回到磁盘。这样将多个插入操作合并进一个操作中,目的是为了减少随机IO带来的性能损耗。

2.3.2 二次写 (double write)

插入缓存给 InnoDB 存储引擎带来了性能上的提升,而 double write 则是保障 InnoDB 存储引擎操作数据页的可靠性。double write 分为两部分组成,一部分在内存中的 double write buffer, 大小为 2MB,另一部分是物理磁盘上共享表空间中连续的128个数据页,即2个区大小(同样是2MB)。在对缓冲池的脏页进行刷新时,并不是直接写磁盘,而是通过 memcpy 函数将脏页复制到内存中的 doublewrite buffer,之后通过doublewrite buffer 在分两次,每次1MB 顺序地写入共享表空间的物理磁盘上,然后马上调用 fsync 将数据同步至磁盘。由于doublewrite 是连续的空间,这样的顺序写IO开销不大。在doublewrite页写完后,再次离散写入各个表空间。如果操作系统在将数据页写入磁盘发生崩溃,那么在恢复的过程中,InnoDB 引擎会从共享表空间中的doublewrite找到该页的一个副本,将其复制到表空间文件,再应用重做日志

2.3.3 自适应hash索引

hash是一种等值查询,InnoDB 存储引擎会监控对表上各个索引页的查询,如果观察到建立hash索引会带来速度提升,则建立相应的索引,因此称为自适应哈希索引(Adaptive Hash Index,AHI)。AHI是通过缓冲池中的B+树页构造而来,建立速度比较快,而且不需要对整张表建立哈希索引,只是建立热点页的索引。AHI默认是开启的状态。

2.3.4 异步IO

为了提高磁盘的操作性能, 当前的数据库系统一般采用异步IO(Asynchronous IO,aiO)的方式来处理磁盘操作,InnoDB 存储引擎也是如此,AIO的优势在于减少SQL查询需要的时间,另外也可以进行IO Merge 操作,就是将多个IO合并为1个IO,这样就可以提高IOPS的性能。

# 开启本地 AIO
show valiables like 'innodb_use_native_aio';

2.3.5 刷新邻接页

InnoDB 存储引擎提供了 Flush Neighbor Page(刷新邻接页)的特性,当刷新一个脏页时,InnoDB 存储引擎会检测该区内是否存在其它脏页,如果存在,则一并进行刷新,这样做得好处显而易见,可以将多个操作合并成一个操作,对于机械硬盘有着明显的优势,但对于固定硬盘,本事就有较高的IOPS,是否开启需要根据情况而定,

参数设置如下:

show varables like 'innodb_flush_neighbors'

3 sql 执行的逻辑

3.1 sql 执行

mysql写文件有2块缓存。一块是自己定义在内存的log buffer, 另一个是磁盘映射到内存的os cache。 mysql可以 调用 flush 主动将log buffer 刷新到磁盘内存映射,也可以调用 fsync 强制操作系同步磁盘映射文件到磁盘。默认情况下innodb_flush_log_at_trx_commit和sync_binlog 配置都为1。

不仅InnoDB引擎中有 buffer 的概念,这个是在用户空间中,而且在内核空间中也有 OS buffer的概念 

 还可以同时调用 flush + fsync, 将缓存直接落盘。
innodb_flush_log_at_trx_commit = 0就是每秒调用 flush + fsync ,定时器自己维护。
innodb_flush_log_at_trx_commit = 1就是实时调用 flush + fsync 没法批处理,性能很低。
innodb_flush_log_at_trx_commit = 2就是实时flush ,定时 fsync 交给OS维护定时器。
sync_binlog 配置
等于0:表示每次提交事务只write不fsync
等于1:表示每次提交事务都执行fsync
等于n:表示事务在write后,会累积N个事务后才fsync。

show variables like 'sync_binlog';
show variables like 'innodb_flush_log_at_trx_commit';
# 查看 mysql 正在执行的进程 
show processlist

InnoDB引擎BufferPool、LogBuffer、OS Buffer、Log files 之间的关系。 

mysql 在执行增删改sql时,InnoDB 引擎的执行步骤如下:

  • 1 执行器拿到需要执行的sql,需要根据更新条件从磁盘中加载需要修改的数据到内存中,也就是存放在 buffer pool 中。
  • 2 在修改对应的数据之前,需要将其数据进行备份,也就是将数据放进 undo log 中,方便在事务回滚时进行操作。
  • 3 直接在内存中按照sql语句修改对应的值。
  • 4 修改完后将按照修改后的数据写 redo log buffer。
  • 5 将 redo log 的内容进行写盘操作,这一步的操作参见 innodb_flush_at_trx_commit 的配置,一般是先写入系统的缓存中,然后由操作系统DMA异步操作写入系统文件中。 flush 操作只是把系统内存中的数据写入操作系统的缓冲中,数据读写一般是由内核线程完成的,这一步是数据从用户线程转变成内核线程进行操作,在读写文件时,在磁盘文件和内存之间会有多级缓存,用于提高数据交换效率,这里的 os cache 起到的就是这个作用。
  • 6 在写完redo log 后,然后进行 bin log 写入操作。
  • 7 和 redo log 的操作类似,也是先写入 os cache 再有操作系统刷到磁盘文件中。sync_log 的配置如图所示。一般情况下,数据库innodb_flush_at_trx_commit 和 sync_log 配置都为 1。
  • 8 在 redo log 和 bin log 写完后,就可以进行事务提交。在数据进行写盘操作时, InnoDB 采用两次写的方式进行写数据。

先写redo log 再写 bin log的原因: 由于mysql 是通过 bin log 进行复制传输的,如果先提交了 redo log,还没有写bin log时出现了宕机,mysql 实例恢复时根据 redo log进行恢复,就会造成 从库和主库之间的数据不一致。

二进制日志文件的记录格式为 statement、row 和 mixed,statement 模式就是直接执行sql,如果其中有函数操作(比如数据库时间设置为 now() )那就会造成数据不准确。row 模式就是同步所有行的数据,如果全表操作修改状态,那这种模式就不合适了,因此在数据同步时需要根据情况采用 mixed 的混合模式。

3.2 FreeList、LRU List 和 Flush List

Free List 空闲列表:

记录所有未被占用的数据页,按照顺序将加载到内存的数据放入buffer pool 中,并删除对应 Free List 中的节点

LRU List LRU 数据访问列表:

将冷热数据块连接起来,根据 LRU 算法进行维护。如果加载进内存的数据一次性放入列表头部,再不确定这批数据的热度情况下,会造成一部分数据的淘汰,mysql InnoDB 的做法是将数据放置在靠后的位置,如果数据在1s内被访问了,才能进入链表头部,即数据热区。

# 将新加载的数据放置在链表的位置 默认为 37 即5/8处,
show variables like 'innodb_old_blocks_pct';
# 冷区数据间隔多久访问才放入链表的热端,默认为1000ms
show variables like 'innodb_old_blocks_time';

Flush List 刷新脏页列表:

记录内存中修改的数据页,使用双向链表进行连接,在方便的时候做落盘操作。

InnoDB 中的 redo log 大小是固定的,在MYSQL数据库Innodb 引擎mvcc实现原理 中提到过 redo log 是保证事务持久性的,其文件个数也是可以根据需要进行配置,通过循环写文件的方式来实现的,当 write pos 追赶上 checkpoint 后,这个时候就不能再继续执行新的命令,需要把check point 往前推进,也就是把redo log 里的内容持久化,腾出空间继续写日志。

数据操作:

redo log buffer 循环写入 :

这里先写日志再写磁盘的关键点也是一个技术,Write-Ahead Logging(WAL技术)。

关于 redo log 的配置可以参见如下命令执行查看。

show variables like '%innodb_log%'
------- 执行结果 ------
innodb_log_buffer_size	16777216
innodb_log_checksums	ON
innodb_log_compressed_pages	ON
innodb_log_file_size	50331648
innodb_log_files_in_group	2
innodb_log_group_home_dir	./
innodb_log_write_ahead_size	8192
innodb_log_buffer_size 为内存中 redo log buffer 的大小,16777216/1024/1024=16MB
innodb_log_file_size 为每个redo log 的大小,50331648/1024/1024=48MB
innodb_log_files_in_group 为 redo log 文件组中文件的个数,默认为2个 
查看数据库表状态
show table status like 'my_table';

到此这篇关于Mysql InnoDB 的内存结构详情的文章就介绍到这了,更多相关Mysql InnoDB 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: Mysql InnoDB 的内存结构详情

本文链接: https://www.lsjlt.com/news/148093.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Mysql InnoDB 的内存结构详情
    目录1 前言2 InnoDB 存储引擎结构2.1 InnoDB表存储引擎文件2.2 InnoDB 预读机制2.3 InnoDB 特性2.3.1 插入缓存2.3.2 二次写 ...
    99+
    2024-04-02
  • MySQL中Buffer Pool内存结构详情
    目录1、回顾一下Buffer Pool是个什么东西?1.1 增删改直接操作的是内存还是磁盘?1.2 数据库崩溃了,内存中数据丢了怎么办?1.3 Buffer Pool的一句话总结2、...
    99+
    2024-04-02
  • Mysql InnoDB引擎的索引与存储结构详解
    前言 在Oracle 和SQL Server等数据库中只有一种存储引擎,所有数据存储管理机制都是一样的。 而MySql数据库提供了多种存储引擎。用户可以根据不同的需求为数据表选择不同的存储引擎,用户也可以根...
    99+
    2024-04-02
  • MySQL的InnoDB存储引擎的数据页结构详解
    目录1 InnoDB页的概念2 数据页的结构3 记录在页中的存储4 Page Directory页目录5 File Header文件头部6 InnoDB页和记录的关系7 没有索引时查...
    99+
    2024-04-02
  • 怎么理解MySQL InnoDB的存储结构
    这篇文章将为大家详细讲解有关怎么理解MySQL InnoDB的存储结构,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 从物理意...
    99+
    2024-04-02
  • 如何理解MySQL数据库Innodb内存结构以及怎样使用内存的
    如何理解MySQL数据库Innodb内存结构以及怎样使用内存的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。概述很多朋友可能会有许多关于I...
    99+
    2024-04-02
  • Mysql InnoDB引擎中的数据页结构详解
    目录Mysql InnoDB引擎数据页结构一、页的简介二、数据页的结构三、记录在页中的存储结构四、记录头信息1. deleted_flag2. min_rec_flag3. n_ow...
    99+
    2024-04-02
  • InnoDB的外存数据结构介绍
    这篇文章主要讲解了“InnoDB的外存数据结构介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“InnoDB的外存数据结构介绍”吧!PartⅠ 表和表空间“...
    99+
    2024-04-02
  • MySQL整体架构与内存结构
    一  mysql 整体框架: MySQL是由SQL接口,解析器,优化器,缓存,存储引擎等组成的。   1. Connectors指的是不同语言中与SQL的交...
    99+
    2024-04-02
  • MySQL中InnoDB索引数据结构(B+树)详解
    mysql的innodb的索引的B+树逐步讲解 B树B+树B树和B+树的不同点聚集索引 VS 非聚集索引总结(面试题)1.为什么不使用二叉查找树?2.为什么不使用平衡二叉树?3.为什么不使用B树?4.为什么MySQL选择B+树做索引...
    99+
    2023-08-17
    b树 数据结构 mysql 数据库
  • MySQL索引底层数据结构详情
    目录一、索引类型 1.B+树 2.MyISAM和InnoDB的B+树索引实现方式的区别(聚簇索引和非聚簇索引)?3.非聚簇索引 4.聚簇索引的优缺点5.哈希索引 6.自适应哈希索引 ...
    99+
    2024-04-02
  • C++控制结构详情
    目录1、顺序结构2、选择结构2.1、if语句2.2、switch语句3、循环结构3.1、while语句3.2dowhile语句3.3for语句4、总结 C++的控制结构和其它编程语言...
    99+
    2024-04-02
  • 详解JAVA中的内存结构与重载
    详解JAVA中的内存结构与重载?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一.对象在JVM的内存结构JAVA内存管理由JVM来管理。1)堆,所有new出来的对象(包括成员...
    99+
    2023-06-14
  • mysql体系结构和InnoDB存储引擎知识有哪些
    这篇文章主要介绍“mysql体系结构和InnoDB存储引擎知识有哪些”,在日常操作中,相信很多人在mysql体系结构和InnoDB存储引擎知识有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方...
    99+
    2024-04-02
  • InnoDB中逻辑存储结构的示例分析
    这篇文章主要为大家展示了“InnoDB中逻辑存储结构的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“InnoDB中逻辑存储结构的示例分析”这篇文章吧。I...
    99+
    2024-04-02
  • JVM入门之JVM内存结构内容详解
    一、java代码编译执行过程 源码编译:通过Java源码编译器将Java代码编译成JVM字节码(.class文件) 类加载:通过ClassLoader及其子类来完成...
    99+
    2024-04-02
  • C++ 继承,虚继承(内存结构)详解
    目录普通的公有继承多重继承虚继承虚继承(菱形继承)总结普通的公有继承 class test1 { public: test1(int i) :num1(i) {} pri...
    99+
    2024-04-02
  • C语言结构体内存对齐详解
    目录实例一:分析:存储结构图如下实例二: 分析:存储结构如下实例三:  分析:存储结构如下 实例四:分析:存储结构图如下总结1、结构体内存对齐...
    99+
    2024-04-02
  • MySQL InnoDB引擎的缓存特性详解
    目录1. 背景2. 存储器性能差异3. Buffer Pool4. Free链表5. Flush链表6. LRU链表7. 其它1. 背景 对于各种用户数据、索引数据等各种数据都是需要...
    99+
    2024-04-02
  • C++结构体与类的区别详情
    C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据类型的数据结构了,它已经获取了太多的功能。 struct能包含成员函数吗? 能! ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作