首页 > 数据库 >【MySQL-存储引擎,逻辑存储结构,内存,磁盘】

【MySQL-存储引擎,逻辑存储结构,内存,磁盘】

时间:2023-03-11 11:32:16浏览次数:36  
标签:存储 NO 索引 InnoDB 内存 MySQL 磁盘 日志

  • 目录:
  • 一、MySQL存储引擎

  • 二、InnoDB存储引擎
  • 1、InnoDB逻辑存储结构
  • 2、InnoDB架构
  • 3、InnoDB内存结构
  • 4、InnoDB磁盘结构


一、MySQL存储引擎

1、查看当前版本支持的存储引擎


show engines;

8.0.26版本,输出结果如下:


+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+

可以看到当前数据库默认使用的是​​InnoDB存储引擎​​,当然也可以建表的时候指定想要使用的存储引擎。

2、常见的存储引擎及特点

  • ① InnoDB:支持事务、支持行锁/表锁、支持外键;
  • ② MyISAM:不支持事务、支持表锁、支持全文索引(InnoDB5.6版本之后);
  • ③ Memory:不支持事务、支持表锁、支持Hash索引。

3、存储引擎的选择

  • ① InnoDB

如果应用对​​事务的完整性​​​有比较高的要求,在并发条件下要求​​数据的一致性​​​,数据操作除了插入和查询之外,还包含很多的​​更新​​​、​​删除​​操作,那么InnoDB存储引擎是比较合适的选择;

  • ② MyISAM

如果应用是​​以读操作和插入操作为主​​,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常合适的;

  • ③ MEMORY

将所有数据保存在内存中,访问速度快,通常用于​​临时表​​​及​​缓存​​。(大小受限、无法保障数据安全)


二、InnoDB存储引擎

【MySQL-存储引擎,逻辑存储结构,内存,磁盘】_数据


1、InnoDB逻辑存储结构

  • ① 表空间(Tablespace)

表空间是InnoDB存储引擎逻辑结构的最高层, 如果用户启用了参数 ​​innodb_file_per_table​​(在8.0版本中默认开启) ,则每张表都会有一个表空间(xxx.ibd),一个mysql实例可以对应多个表空间,用于存储记录、索引等数据。


show variables like '%innodb_file_per_table%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+

查看.ibd文件存储位置的命令:​​show global variables like '%datadir%';​​​,位置为​​/var/lib/mysql/​​,如下:


show global variables like '%datadir%';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| datadir | /var/lib/mysql/ |
+---------------+-----------------+

【MySQL-存储引擎,逻辑存储结构,内存,磁盘】_表空间_02


  • ② 段(Segment)

段,分为​​数据段(Leaf node segment)​​​、​​索引段(Non-leaf node segment)​​​、​​回滚段(Rollback segment)​​​,段用来管理多个Extent(区)。
关于段举例:InnoDB是索引组织表,数据段就是B+树的叶子节点, 索引段即为B+树的非叶子节点。

  • ③ 区(Extent)

区,表空间的单元结构,每个区的大小为​​1M​​​。 默认情况下, InnoDB存储引擎页大小为16K, 即一个区中一共有​​64个连续的页​​。

  • ④ 页(Page)

页,是InnoDB 存储引擎磁盘管理的最小单元,每个页的大小默认为 ​​16KB​​​。为了保证页的连续性,InnoDB 存储引擎​​每次从磁盘申请 4-5 个区​​。

  • ⑤ 行(Row)

行,InnoDB 存储引擎数据是按行进行存放的。

在行中,默认有两个隐藏字段:

  • ​Trx_id​​​:每次对某条记录进行改动时,都会把对应的​​事务id​​赋值给trx_id隐藏列。
  • ​Roll_pointer​​​:每次对某条引记录进行改动时,都会把旧的版本写入到undo日志中,然后这个隐藏列就相当于一个指针,可以通过它来找到该​​记录修改前的信息​​。

2、InnoDB架构

官方文档查看位置: InnoDB Architecture

【MySQL-存储引擎,逻辑存储结构,内存,磁盘】_存储引擎_03


3、InnoDB内存结构

内存结构包含:​​Buffer Pool​​​、​​Change Buffer​​​、​​Adaptive Hash Index​​​、​​Log Buffer​​。

  • ① Buffer Pool(缓冲池)

Ⅰ 缓冲池官方文档:Buffer POOL

在专用服务器上,通常将多达80%的物理内存分配给缓冲池 。


show variables like 'innodb_buffer_pool_size';
+-------------------------+-----------+
| Variable_name | Value |
+-------------------------+-----------+
| innodb_buffer_pool_size | 134217728 |
+-------------------------+-----------+

在InnoDB的缓冲池中不仅缓存了​​索引页​​​和​​数据页​​​,还包含了​​undo页​​​、​​插入缓存​​​、​​自适应哈希索引​​​以及​​InnoDB的锁信息​​等等。

缓冲池 Buffer Pool,是主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增删改查操作时,先操作缓冲池中的数据(若缓冲池没有数据,则从磁盘加载并缓存),然后再以一定频率刷新到磁盘,从而减少磁盘IO,加快处理速度。

缓冲池以Page页为单位,底层采用链表数据结构管理Page。根据状态,将Page分为三种类型:

  • free page:空闲page,未被使用。
  • clean page:被使用page,数据没有被修改过。
  • dirty page:脏页,被使用page,数据被修改过,也中数据与磁盘的数据产生了不一致。
  • ② Change Buffer(更改缓冲区)

Ⅰ 更改缓冲区官方文档:  Change Buffer

更改缓冲区是一种特殊的数据结构,当 二级索引页​​​不在​缓冲池中时,它将缓存这些页的更改。由INSERT、UPDATE DELETE(DML) 操作导致的缓冲更改先保存在更改缓冲区,在未来数据被读取时,再将数据合并恢复到Buffer Pool中,再将合并后的数据刷新到磁盘中。

【MySQL-存储引擎,逻辑存储结构,内存,磁盘】_存储引擎_04


聚集索引不同,二级索引通常是非唯一的,并且插入到二级索引中按相对随机的顺序发生。同样,删除和更新可能会影响不在索引树中相邻的二级索引页。这些大量随机访问的 I/O会大大影响效率,在更改缓冲区中对这些​​更改做合并​​​,以​​减少IO操作​​。

  • ③ Adaptive Hash Index(自适应哈希索引)

Ⅰ 自适应哈希索引官方文档: Adaptive  Hash  Index

hash索引在进行等值匹配时,一般性能是要高于B+树的。InnoDB存储引擎会监控对表上各索引页的查询情况,根据实际情况判断是否创建自适应哈希索引。自适应哈希索引,无需人工干预,是系统根据情况​​自动完成​​。


show variables like 'innodb_adaptive_hash_index';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| innodb_adaptive_hash_index | ON |
+----------------------------+-------+

  • ④ Log Buffer(日志缓冲区)

Ⅰ 日志缓冲区官方文档:  Log  Buffer

日志缓冲区,用来保存要写入到磁盘中的log日志数据(​​redo log​​​、​​undo log​​​),​​默认大小为 16MB​​,日志缓冲区的日志会定期刷新到磁盘中。如果需要更新、插入或删除许多行的事务,增加日志缓冲区的大小可以节省磁盘 I/O。

查看缓冲区大小:


show variables like 'innodb_log_buffer_size';
+------------------------+----------+
| Variable_name | Value |
+------------------------+----------+
| innodb_log_buffer_size | 16777216 |
+------------------------+----------+

刷盘时机参数:


show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1 |
+--------------------------------+-------+

刷盘时机参数说明:

  • 0: 每秒将日志写入并刷新到磁盘一次;
  • 1: 日志在每次事务提交时写入并刷新到磁盘,默认值;
  • 2: 日志在每次事务提交后写入,并每秒刷新到磁盘一次。

4、InnoDB磁盘结构

  • ① The System Tablespace(系统表空间)

Ⅰ 系统表空间官方文档: The  System  Tablespaces。

系统表空间是更改缓冲区的存储区域。如果表是在系统表空间中创建的,而不是在按表的文件或常规表空间中创建的,则它还可能包含表和索引数据。(在MySQL5.x版本中还包含InnoDB数据字典、undolog等)。


show variables like 'innodb_data_file_path';
+-----------------------+------------------------+
| Variable_name | Value |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:12M:autoextend |
+-----------------------+------------------------+

系统表空间,默认的文件名: ​​ibdata1​​。

  • ② File-Per-Table Tablespaces(每个表的文件空间)

Ⅰ 每个表的文件空间官方文档: File-Per-Table  Tablespaces。

每个表的文件表空间包含单个表的数据和索引,并存储在文件系统上的单个数据文件中(​​.ibd文件​​)。


show variables like 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+

  • ③ General Tablespaces(常规表空间)

Ⅰ 常规表空间官方文档: General   Tablespaces

语法:


CREATE TABLESPACE tablespace_name
[ADD DATAFILE 'file_name']
[FILE_BLOCK_SIZE = value]
[ENGINE [=] engine_name]

在数据目录中创建常规表空间:


CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB;

创建表:


CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1;

  • ④ Undo Tablespaces(撤消表空间)

Ⅰ 撤消表空间官方文档:  Undo  Tablespaces

撤销表空间,MySQL实例在初始化时会自动创建两个默认的undo表空间(初始大小16M),用于存储undo log日志。

  • ⑤ Temporary Tablespaces(临时表空间)

Ⅰ 临时表空间官方文档: Temporary  Tablespacs

InnoDB 使用会话临时表空间和全局临时表空间。存储用户创建的临时表等数据。

  • ⑥ Doublewrite Buffer Files(双写缓冲区)

Ⅰ 双写缓冲区官方文档: Doublewrite   Buffer

双写缓冲区,innoDB引擎将数据页从Buffer Pool刷新到磁盘前,先将数据页写入双写缓冲区文件中,便于系统异常时恢复数据。


#ib_16384_0.dblwr
#ib_16384_1.dblwr

  • ⑦ Redo Log(重做日志)

Ⅰ 重做日志官方文档:   Redo  Log

重做日志,是用来实现事务的持久性。该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都会存到该日志中, 用于在刷新脏页到磁盘时,发生错误时,进行数据恢复使用。


三、结尾

以上即为MySQL-存储引擎的部分内容


标签:存储,NO,索引,InnoDB,内存,MySQL,磁盘,日志
From: https://blog.51cto.com/u_15874356/6112493

相关文章

  • db + mysql vs oracle
    smysql与oracle的几点区别序号mysqloracle备注1.组函数用法规则mysql中组函数在select语句中可以随意使用oracle中如果查询语句中有组函数,那其他列名必须是......
  • 《高性能mysql》之高性能索引创建(第五章)
    ①索引的类型: --B-Tree索引:加快访问数据的速度,因为存储引擎不再需要全表扫描而是从索引根节点开始搜索           使用范围:全值匹配、......
  • 《高性能mysql》之性能分析(第三章)
    额外:吞吐量是性能优化的副产品作用:性能分析确定哪些子任务是优化目标,测量出响应时间花在哪分析MySQL查询:     慢查询日志:     ①安装使用教程......
  • mysql: Specified key was too long; max key length is 767 bytes
    问题记录:原因如果该字段参与了索引,在对该字段进行拓展长度时会提示超过索引最大值我使用的解决方案,在使用联合索引时使用改字段的前一部分作为联合索引\然后再......
  • docker安装MySQL
    docker安装MySQL1、先安装docker略过。2、准备工作先准备配置目录和持久化目录,举个栗子:mkdir-p/opt/mysql/{conf,data}准备配置文件*.cnf,放到/opt/mysql/conf目......
  • C语言之数据的存储(一)(整型数据)
    一、整型数据在内存中的存储1.1整型数据家族char,short,intlong(每种类型又分为unsigned和signed,例如,signedchar,unsignedchar)1.2整型数据的存储对于整型数据,其在计......
  • php 连接不上 mysql 应该怎么办?
    当PHP无法连接到MySQL时,您可以尝试以下步骤:检查服务和配置1.检查MySQL服务器是否正在运行。您可以通过在终端运行以下命令来检查:sudosystemctlstatusmysql如果MyS......
  • What is the difference between utf8mb4 and utf8 charsets in MySQL?
    Whatisthedifferencebetweenutf8mb4andutf8charsetsinMySQL?回答1UTF-8isavariable-lengthencoding.InthecaseofUTF-8,thismeansthatstoringo......
  • [第五空间 2021]yet_another_mysql_injection
    [第五空间2021]yet_another_mysql_injectionF12查看源代码发现?source提示,<?phpinclude_once("lib.php");functionalertMes($mes,$url){die("<script>alert('......
  • mysql锁总结
    概述:锁是在并发访问时,解决数据的有效性、一致性问题,有全局锁、表级锁、行级锁,锁粒度越小越好。全局锁:是对整个数据库实例加锁,一旦对整个数据库实例加了锁,那么就意味着这个......