首页 > 数据库 >MySQL InnoDB存储引擎

MySQL InnoDB存储引擎

时间:2024-05-25 08:56:28浏览次数:22  
标签:存储 链表 索引 InnoDB MySQL 日志

一、存储引擎的简介
MySQL 5.7 支持的存储引擎有 InnoDB、MyISAM、Memory、Merge、Archive、Federated、CSV、BLACKHOLE 等。

1、InnoDB存储引擎
从MySQL5.5版本之后,默认内置存储引擎是InnoDB,主要特点有:
(1)灾难恢复性比较好;
(2)支持事务。默认的事务隔离级别为可重复读,通过MVCC(并发版本控制)来实现的。
(3)使用的锁粒度为行级锁,可以支持更高的并发;
(4)支持外键;
(5)配合一些热备工具可以支持在线热备份;
(6)在InnoDB中存在着缓冲管理,通过缓冲池,将索引和数据全部缓存起来,加快查询的速度;
(7)支持聚簇索引。对于InnoDB类型的表,其数据的物理组织形式是聚簇表。所有的数据按照主键来组织。数据和索引放在一块,都位于B+数的叶子节点上,通过聚簇索引来查询可以减少回表查询。
(8)InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描
(9)支持B-tree索引和全文检索( MySQL 5.6后InnoDB存储引擎开始支持全文检索)
(10)不支持Hash索引,但是内置了自适应hash索引。

2、MyISAM存储引擎
在5.5版本之前,MyISAM是MySQL的默认存储引擎,该存储引擎并发性差,不支持事务,所以使用场景比较少,主要特点为:
(1)不支持事务;
(2)不支持外键,如果强行增加外键,不会提示错误,只是外键不其作用;
(3)不支持聚簇索引,对数据的查询缓存只会缓存索引,不会像InnoDB一样缓存数据,而且是利用操作系统本身的缓存;
(4)默认的锁粒度为表级锁,所以并发度很差,加锁快,锁冲突较少,所以不太容易发生死锁;
(5)支持全文索引(MySQL5.6之后,InnoDB存储引擎也对全文索引做了支持),但是MySQL的全文索引基本不会使用,对于全文索引,现在有其他成熟的解决方案,比如:ElasticSearch,Solr,Sphinx等。
(6)数据库所在主机如果宕机,MyISAM的数据文件容易损坏,而且难恢复;

二、InnoDB的结构组成


1、内存结构
1.Buffer Pool(读缓冲池)


缓冲池是主内存中的一个区域,InnoDB在访问表和索引数据时会在其中进行缓存,避免每次访问都进行磁盘IO。
Buffer Pool的三个链表,LRU链表、free链表、flush链表。
free链表:双向链表,每个节点缓存页的描述数据块的地址。
flush链表:被修改过的缓存页的描述数据块,组成的双向链表,后续都是要flush刷新到磁盘上去。
LRU链表:将频繁访问的数据放在链表头部,不怎么访问的数据链表末尾,空间不够的时候就从尾部开始淘汰。

2.Change Buffer(写缓冲池)
如果发生变化的辅助索引页不在buffer pool里,由Change Buffer先缓存这些辅助索引页的变更动作。
等辅助索引页被读取时,再将数据再将数据合并(merge)恢复到缓冲池中的技术;或者定期对写辅助索引页的changes buffer进行合并,写到到buffer pool 中。目的是降低写操作的磁盘IO,提升数据库性能。

为什么change buffer只对辅助索引生效?
以insert新增操作为例,插入顺序一般是按照主键递增顺序进行插入的,插入聚集索引(主键索引)一般是顺序的,不需要磁盘的随机读取。
这种情况下对聚集索引的修改速度是非常快的,所以不需要进行写缓冲。
而对于辅助索引的插入或者更新操作,由于B+树的索引结构的特性决定了辅助索引插入的离散型。
所以,对于辅助索引的插入或者更新操作,InnoDB中不是每一次都直接插入到索引页中,而是先判断插入的辅助索引页是否在缓存区中,若在直接插入;
若不在,则先放入到change buffer中,然后再以一定频率和情况进行change buffer和辅助索引页子节点的merge(合并)操作,
这时通常能将多个插入合并到一个操作中(因为在一个索引页中),这就大大提高了对于辅助索引插入的性能。

3.自适应hash索引(Adaptive Hash Index,AHI)
InnoDB存储引擎会监控对表上各索引页的查询,如果观察到建立hash索引可以提高查询速度,则自动建立hash索引,索引的索引。

4. Log Buffer(日志缓冲)
保存要写入磁盘上的日志文件数据的内存区域,由innodb_log_buffer_size变量定义大小,默认16MB。
日志缓冲区的内容定期刷新到磁盘,较大的日志缓冲区使大型事务可以运行,而无需在事务提交之前将redo日志数据写入磁盘。
插入或删除许多行的事务,增加日志缓冲区的大小可以节省磁盘I/O。

2、磁盘结构
1、表
2、索引
3、表空间


系统表空间
系统表空间是存放change buffer的区域。
表单文件表空间
每个表的数据和索引都会采用单独的文件进行保存。是否启动 file-per-table表空间是由innodb_file_per_table属性来控制的。
常规表空间
常规表空间是使用 CREATE TABLESPACE 语法创建的共享InnoDB表空间。是共享的表空间,一个文件能够存储多个表数据,常规表空间由于多表共享表空间,消耗的内存会更少一点,具有潜在的内存优势。
Undo表空间
回滚表空间,用来保存回滚日志,即undo logs。
临时表空间(Temporary Tablespaces)
InnoDB使用会话临时表空间和全局临时表空间。

4、Doublewrite Buffer(双写缓冲)
doublewrite 缓冲区是一个存储区域,InnoDB在将页面写入InnoDB数据文件中之前,会写入从缓冲池中刷新的页面。
如果在页面写入过程中发生操作系统,存储子系统或mysqld进程崩溃,则InnoDB可以在崩溃恢复期间从doublewrite缓冲区中找到该页面的良好副本。
MySQL 8.0.20之前,doublewrite缓冲区存储区位于InnoDB系统表空间中。
MySQL 8.0.20开始,doublewrite缓冲区存储区位于doublewrite文件中。

5、Redo Log(重做日志)
基于磁盘的数据结构,主要防止在崩溃恢复期间用于纠正不完整事务写入的数据。
正常操作时,重做日志对更改表数据的请求进行编码记录。初始化时,自动重播未完成意外关闭之前未完成更新数据文件的修改。
默认情况下,redo log会自动生成2个文件。

6、Undo Logs(回滚日志)
回滚日志主要是为了支持事务回滚功能。默认会生成2个回滚日志,保存在undo tablespaces下。

补充:二进制日志(binlog)
binlog是记录所有数据库表结构变更(例如CREATE、ALTER TABLE…)以及表数据修改(INSERT、UPDATE、DELETE…)的二进制日志。
用于数据恢复和数据复制
MySQL正是通过主服务器的二进制日志来实现数据的传递。主服务器上的二进制日志内容会被发送到各个从服务器,并在每个从服务器上执行,从而保证了主从服务器之间数据的一致性。
在默认配置下,MySQL不记录二进制日志。可以通过设置参数–log-bin=[base_name]启用二进制日志功能。

三、SQL的执行
1、查询流程

2、写入流程

http://cainiao.guashuw.com/

标签:存储,链表,索引,InnoDB,MySQL,日志
From: https://www.cnblogs.com/dbbull/p/18211982

相关文章

  • Mysql自增id、uuid、雪花算法id的比较
    MySQL自增id:优点:1.简单易用​MySQL自增id由数据库自动生成。2.效率高自增id是按顺序递增的,可以提高插入和查询的效率。3.索引效率高自增id可以作为主键或索引列,提高查询效率。缺点:1.不适用于分布式系统在分布式环境下,多个节点生成的自增id可能会冲突,需要额外的处理机......
  • 在Linux下管理MySQL的大小写敏感性
    当开发与Linux环境下MySQL数据库交互的Java应用程序时,理解MySQL中的大小写敏感性可以避免潜在的错误和问题。本指南深入探讨了MySQL中的大小写敏感设置,比较了5.7和8.0版本,并为Java开发者提供了最佳实践。1理解MySQL中的大小写敏感性默认情况下,MySQL在Windows上是大小写不敏感的......
  • 联网安装与源码安装mysql
    一、卸载mariadb的rpm包1、首先,你需要找出已安装的MariaDB包的具体名称。可以使用以下命令列出所有已安装的MariaDB包:rpm-qa|grepmariadb2、删除命令(安装mysql不一定需要卸载)yum-yremove+【上图的文件名】或者rpm-e--nodeps+【上图的文件名】二、通过yum在线安装M......
  • The configuration for MySQL Server 8.0.27 has failed You can find more informati
    遇见这种情况,作者当时也是痛苦万分,网上找了许许多多的方法试了好多次都不行。分析问题出现这种问题是因为我们之前安装过但是没有安装完全就取消了,电脑里面已经存储了。重新安装的时候把安装位置和数据存放的位置路径全部使用英文,例如:之前我的安装路径:D:\用户\app\mysql......
  • 玩转STM32-直接存储器DMA(详细-慢工出细活)
    文章目录一、DMA介绍1.1DMA简介1.2DMA结构二、DMA相关寄存器(了解)三、DMA的工作过程(掌握)四、DMA应用实例4.1DMA常用库函数4.2实例程序一、DMA介绍1.1DMA简介DMA用来提供外设与外设之间、外设与存储器之间、存储器与存储器之间的高速数据传输,无需CPU干预,数据可......
  • Mysql事务
    1.概述事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。注意:默认MySQL的事务是自动提交的,也就是说,当执行完一条DML语句时,MySQL会立即隐式的提交事务。2.事务操作2.1方......
  • MySQl存储引擎
    1.体系结构1.1连接层最上层是一些客户端和链接服务,包含本地sock通信和大多数基于客户端/服务端工具实现的类似于TCP/IP的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念,为通过认证安全接入的客户端提供线程。同样在该层上可......
  • MySQL查询某个字段含有字母数字的值
    1.正则表达式(REGEXP)查询MySQL表中某个字段含有字母和数字的值,可以使用正则表达式(REGEXP)来匹配这样的模式。在MySQL中,正则表达式是一个强大的工具,可以用来搜索和匹配字符串中的特定模式。假设我们有一个名为my_table的表,并且我们想要查询名为my_column的字段,这个字段包含至少一个......
  • MySQL查询某个字段含有字母数字的值
    1.正则表达式(REGEXP)查询MySQL表中某个字段含有字母和数字的值,可以使用正则表达式(REGEXP)来匹配这样的模式。在MySQL中,正则表达式是一个强大的工具,可以用来搜索和匹配字符串中的特定模式。假设我们有一个名为my_table的表,并且我们想要查询名为my_column的字段,这个字段包含至少......
  • MySQL 5.7 升级到 8.0
    1.升级前检查wgethttps://downloads.mysql.com/archives/get/p/43/file/mysql-shell-8.0.36-linux-glibc2.12-x86-64bit.tar.gztarxfmysql-shell-8.0.36-linux-glibc2.12-x86-64bit.tar.gz-C/tmp/cd/tmp/mysql-shell-8.0.34-linux-glibc2.12-x86-64bit/bin./mysqlsh-u......