二、MySQL底层存储原理与结构

2023-10-26

1 前言

本章目标:

  • 了解构成MySQL数据库和InnoDB存储引擎的各种类型的文件。
  • 理解InnoDB存储引擎的内存结构和磁盘结构。

2 文件

MySQL数据库和InnoDB存储引擎的文件有参数文件、日志文件、socket文件、pid文件、表结构文件、存储引擎文件。下面将会对这些文件逐一介绍。

参数文件

告诉MySQL实例启动时在哪里可以找到数据库文件,并且指定某些初始化参数,这些参数定义了某种内存结构的大小等设置,还会介绍各种参数的类型。
可以使用show variables查看数据库中的所有参数,也可以通过LIKE来过滤参数名,如 show variables like ‘innodb_buffer%’;
MySQL参数文件中的参数可以分为两类:动态参数和静态参数。动态参数可以在MySQL实例运行中进行更改,静态参数在整个实例生命周期内都不能进行更改。

日志文件

日志文件是用来记录MySQL实例对某种条件做出相应执行时写入的文件。MySQL中有六种日志文件,分别是:错误日志(error log)、常规查询日志(general log)、二进制日志(bin log)、慢查询日志(slow query log)、重做日志(redo log)、回滚日志(undo log)、中继日志(relay log)。

  • 错误日志(error log)
    错误日志记录MySQL的启动、运行、关闭过程信息。该日志不但记录了出错信息,也记录了警告或正确的信息,通过分析错误日志可以快速定位故障进行排错。可使用show variables like 'log_error’查看当前的错误日志配置。
    请前往【MySQL官网-错误日志】,了解更多详细信息。

  • 常规查询日志(general log)
    当客户端连接或断开连接时,服务器将信息写入此日志,并记录从客户端接收的每个 SQL语句。建议关闭这种日志(默认是关闭的)。
    请前往【MySQL官网-常规查询日志】,了解更多详细信息。

  • 二进制日志(bin log)
    包含二进制文件“事件”描述数据库更改,如表创建操作或对表数据的更改。它还包含可能已进行更改的语句的事件(例如删除),除非使用基于行的日志记录。二进制日志还包含有关每个语句占用更新数据的时间的信息。二进制日志有两个重要用途:
    a. 对于复制,复制源服务器上的二进制日志提供要发送到副本的数据更改的记录。 源将其二进制日志中包含的事件发送到其副本,副本执行这些事件以进行与源服务器上相同的数据更改。
    b. 某些数据恢复操作需要使用二进制日志。恢复备份后,将重新执行备份后记录的 二进制日志中的事件。这些事件使数据库从备份点开始保持最新状态。
    请前往【MySQL官网-二进制日志】,了解更多详细信息。

  • 慢查询日志(slow query log)
    待补充,敬请期待…

  • 重做日志(redo log)
    待补充,敬请期待…

  • 回滚日志(undo log)
    待补充,敬请期待…

  • 中继日志(relay log)
    待补充,敬请期待…

socket文件

当用UNIX域套接字方式进行连接时需要的文件。

pid文件

MySQL实例的进程ID文件。

表结构文件

用来存放MySQL表结构定义文件。

存储引擎文件

因为MySQL表存储引擎的关系,每个存储引擎都会有自己的文件来保存各种数据。这些存储引擎真正存储了记录和索引等数据。

3. InnoDB 体系结构

在这里插入图片描述
上图展示了InnoDB 存储引擎的内存结构和磁盘结构。

4 内存结构

InnoDB内存数据对象如下图:
在这里插入图片描述
InnoDB 提供了自己的内存组件,主要包括缓冲池(Buffer Pool)、变更缓冲(Change Buffer)、日志缓冲(Log Buffer)以及自适应哈希索引(Adaptive Hash Index)技术。

缓冲池

缓冲池是 InnoDB 在内存中的一个缓冲区域,主要用于缓存访问过的表和索引等数据。缓冲池利用内存直接处理数据,避免磁盘操作,从而加快了数据处理的速度。
使用show variables like ‘innodb_buffer_pool%’;命令可查看InnoDB 缓冲池相关的配置:

mysql> SHOW VARIABLES LIKE 'innodb_buffer_pool%';
+-------------------------------------+----------------+
| Variable_name                       | Value          |
+-------------------------------------+----------------+
| innodb_buffer_pool_chunk_size       | 8388608        |
| innodb_buffer_pool_dump_at_shutdown | ON             |
| innodb_buffer_pool_dump_now         | OFF            |
| innodb_buffer_pool_dump_pct         | 25             |
| innodb_buffer_pool_filename         | ib_buffer_pool |
| innodb_buffer_pool_in_core_file     | ON             |
| innodb_buffer_pool_instances        | 1              |
| innodb_buffer_pool_load_abort       | OFF            |
| innodb_buffer_pool_load_at_startup  | ON             |
| innodb_buffer_pool_load_now         | OFF            |
| innodb_buffer_pool_size             | 8388608        |
+-------------------------------------+----------------+
11 rows in set (0.00 sec)

缓冲池管理算法

缓冲池通过LRU(Latest Recent Used,最近最少使用)算法进行管理。最频繁使用的页在LRU列表的前端,而最少使用的页在LRU列表的尾端。当缓冲池不能存放新读取的页的时候,将首先释放LRU列表中尾端的页。

变更缓冲

待补充,敬请期待…

日志缓冲

待补充,敬请期待…

自适应哈希索引

待补充,敬请期待…

5. 磁盘结构

InnoDB逻辑存储结构

InnoDB存储引擎所有数据都被逻辑地存放在一个表空间。表空间由段(segment)、区(extent)、页(page)组成。如下图所示:

在这里插入图片描述

  • 表空间:在默认情况下,InnoDB存储引擎所有数据都存放于一个表空间。可通过“innodb_file_per_table”参数可以使每张表内的数据单独存放到一个表空间,需要注意的是,这些独立的表空间存放的只是数据、索引和插入缓冲,而Undo信息、事务信息、双写缓冲等还是存放在共享表空间。
  • 段:常见的有数据段、索引段、回滚段等。InnoDB存储引擎表是索引组织的,数据即索引,索引即数据。那么数据段即为B+树的叶子节点(leaf node segment),索引段即为B+树的非叶子节点(non-leaf node segment)。
  • 区:由64个连续的页组成的,每个页大小为16KB,即每个区的大小为1MB。对于大的数据段,InnoDB存储引擎最多每次可以申请4个区,以此来保证数据的顺序性能。在启用了参数innodb_file_per_talbe后,创建的表默认大小是96KB,这里不是默认不是1M的原因是:在每个段开始时,先有32个页大小的碎片页(fragment page)来存放数据,当这些页使用完之后才是64个连续页的申请。
  • 页:页是InnoDB磁盘管理的最小单位。InnoDB页默认大小16KB(操作系统页式管理中的页大小为4KB,InnoDB存储引擎申请连续的4页)。常见的页类型有:数据页、Undo页、系统页、事务数据页、插入缓冲位图页、插入缓冲空闲列表页、未压缩的二进制大对象页、压缩的二进制大对象页。
  • 行:InnoDB存储引擎是面向行的(row-oriented),每个页最多允许存放(16KB/2-200)行的记录,即7992行记录。

InnoDB数据页结构

待补充,敬请期待…

InnoDB行记录格式

InnoDB存储引擎提供了Compact 和 Redundant 两种格式来存放行记录数据,这也是目前使用最多的一种格式。Redundant 格式是为了兼容之前版本而保留的,MySQL 5.1之后的版本默认为 Compact 行格式。可以使用命令SHOW TABLE STATUS LIKE 'table_name’来查看当前表使用的行格式。

Compact 行记录格式如下:
在这里插入图片描述

  • 首部是一个非 NULL 变长字段长度列表,并且是按照列的顺序逆序放置的,长度为:若列的长度小于255字节,则用1字节表示;若大于255个字节,用2字节表示。变长字段的长度不可以超过两个字节,因为 VARCHAR 类型的最大长度限制为 65535。
  • 变长字段之后的第二个部分是 NULL 标志位,该位指示了该位数据中是否有 NULL 值,有则用1表示。
  • 接下来的部分是记录头信息(record header),固定占用5字节(40位)。
  • 最后的部分就是实际存储每个列的数据。需要特别注意的是,NULL 不占用该部分任何空间,即 NULL 除了占用 NULL 标志位之外,实际存储不占用空间。另外,每行数据除了用户定义的之外,还有两个隐藏列,事务ID列和回归指针列,分别是6和7字节大小。如果 InnoDB 表没有定义主键,还会增加一个6字节的 rowid 列。

双写缓冲

待补充,敬请期待…

上一篇:一、MySQL体系结构
下一篇:三、MySQL索引与算法

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

二、MySQL底层存储原理与结构 的相关文章

  • 在 PHP 字符串中格式化 MySQL 代码

    是否有任何程序 IDE 可以在 PHP 字符串中格式化 MySQL 代码 例如 我使用 PHPStorm IDE 但它无法做到这一点 它对 PHP 和 MYSQL 执行此操作 但不适用于 php 字符串内的 MYSQL 我已准备好使用新的
  • 在 MySQL 中存储表情符号的编码问题:如何使用 Prisma ORM 在 NodeJS 中定义字符排序规则?

    亲爱的 Nodejs 专家和数据库专家 我们在 MySQL 数据库中存储表情符号和其他特殊字符时遇到问题 我们使用 Prisma 得到一个错误 这是我们使用的 ORM 参数无法从排序规则 utf8 general ci 转换为 utf8mb
  • POINT 列上的 MySQL INSERT/UPDATE

    我正在尝试用我国家的地理位置填充我的数据库 我的一张表有 4 个字段 ID PK 纬度 经度和地理点 EDIT SCDBs Punto Geografico SET lat 18 469692 SET lon 63 93212 SET g
  • 在mysql中的单个查询中更新多个表

    我有三个查询 我想要一个 这是我的查询 UPDATE tab1 SET a WHERE id 3 UPDATE tab2 SET b WHERE id 9 UPDATE tab3 SET c WHERE id 5 您可以尝试下面的代码 UP
  • 显示标准化数据

    跟进问题 添加 2 个不同表的总和 https stackoverflow com questions 39717541 adding sum from 2 different tables 我创建了3个表 members videos v
  • 如果没有找到值,如何让 MySQL 中的 SUM 函数返回“0”?

    假设我在 MySQL 中有一个简单的函数 SELECT SUM Column 1 FROM Table WHERE Column 2 Test 如果没有条目Column 2 包含文本 Test 然后该函数返回NULL 而我希望它返回 0 我
  • SQL Join 列上类似于另一列[重复]

    这个问题在这里已经有答案了 可能的重复 mysql连接查询使用like https stackoverflow com questions 1930809 mysql join query using like 我想要进行连接 其中一列包含
  • 使用Perl/DBI/MySQL/InnoDB查找外键信息

    我想以编程方式查找 MySQL 数据库中特定 InnoDB 表的外键 我正在使用 Perl 我偶然发现 dbh gt foreign key info 我刚刚尝试使用它 但似乎有点错误 它不会返回 ON DELETE 和 ON UPDATE
  • 如果 Row1 = 值 1,则更新其他行

    我有一个小的 php 脚本 用于访问 mySql 数据库 我想在数据库中插入新记录之前查看该数字 值 1 是否等于数据库中的记录 这也在第 1 行 所以我想 查看传入的电话号码是否等于数据库中的电话号码 如果是这样 则必须保持电话号码相同的
  • 错误代码:1305。函数或过程不存在

    因此 我在 MySQL 中创建一个函数 然后尝试向用户授予使用该函数的权限 但我无法这样做 这就是我正在做的 DELIMITER USE rxhelp36 scbn DROP FUNCTION IF EXISTS businessDayDi
  • mysql 中的二进制、十六进制和八进制值

    我对在 mysql 数据库中使用二进制 十六进制和八进制系统非常感兴趣 首先 请给我一个建议 为什么我们在存储信息时需要它们 因为信息太多 或者为什么 另外 哪种类型的值必须存储在标记系统中 另外这里还有像 这是例子 gt SELECT 5
  • 用 pandas DataFrame 替换 mysql 数据库表中的行

    Python 版本 2 7 6 熊猫版本 0 17 1 MySQLdb 版本 1 2 5 在我的数据库中 PRODUCT 我有一张桌子 XML FEED 表 XML FEED 很大 数百万条记录 我有一个 pandas DataFrame
  • 如何在 SEQUELIZE (nodeJS) 中创建触发器?

    我正在尝试使用sequelize 创建一个触发器 主要思想是创建一个实例CONFIG创建后USER USER MODEL module exports function sequelize DataTypes var User sequel
  • 如何在MYSQL中将整个字符串小写并保持第一个大写[重复]

    这个问题在这里已经有答案了 我的表栏目 我预期的输出会在列中发生变化 Smith Allen Doyle Dennis Baker Waker 这是我尝试过的 但不起作用 UPDATE TABLE employee SET last nam
  • 将庞大数据库从亚马逊RDS导出到本地mysql

    我在 Amazon RDS 上有一个 mysql 数据库 大约 600GB 数据 我需要将其移回本地专用服务器 但我不知道从哪里开始 每次我尝试初始化 sqldump 时它都会冻结 有没有办法将其移至 S3 甚至可能在开始下载之前将其分成更
  • 如何通过Elasticsearch模糊匹配电子邮件或电话?

    我想通过 Elasticsearch 对电子邮件或电话进行模糊匹配 例如 匹配所有以以下结尾的电子邮件 gmail com or 匹配所有电话开头136 我知道我可以使用通配符 query wildcard email gmail com
  • MYSQL - 使用逗号分隔字符串作为变量输入的存储过程

    我希望有人能够提供帮助 我已经创建了我的第一个存储过程 没什么花哨的 但是我遇到了问题 我想给它一个字符串输入 例如 1 2 3 4 5 然后它执行一个简单的操作SELECT FROM TABLE WHERE EAN IN VAR 所以存储
  • MYSQL从每个类别中随机选择一条记录

    我有一个数据库Items表看起来像这样 id name category int 有几十万条记录 每个item可以是 7 种不同的之一categories 对应于categories table id category 我想要一个从每个类别
  • mysql排序和排名语句

    我需要一些 mysql 语句的帮助 我的表 1 有 7 列 表 2 有 8 列 额外的列名为排名 我的语句应该是这样的 从表 1 中选择全部 然后按 用户数 排序 将其插入表 2 中并排名开始 1 2 3 等 table 1 usernam
  • MySQL 转储未知选项“-no-beep”

    在旧服务器上我使用了mysql转储命令来备份 MySQL 数据库 在新服务器上 MySQL 版本为 5 6 相同的命令给出了错误 unknown option no beep 无论它插入什么 我也在互联网上搜索过 但找不到任何帮助 在 my

随机推荐

  • scala ide + helloworld

    http blog csdn net asongoficeandfire article details 21490101 简介 在上一篇文章中 我们阐述了Coursera使用Scala的理由 以及Scala的优缺点 说多不如少练 我们今天
  • 一文讲透缓存方案及常见问题——初篇

    Hello 大家好 今天跟大家聊的一个话题就是 缓存 目前 面向C端的服务架构中 除开管理后台等访问量很少 实时性要求较高的服务可不使用缓存外 缓存已成为高性能分布式系统里不可或缺的一环 本文不打算过多涉及具体的缓存组件如Memcached
  • Python读取文件并修改文件内容后保存为新文件

    下面是例子是读取一个文件内容 并且改变其中满足正则的行 进行内容追加 use command reWriteFile py oldFileName txt newFileName txt import re import sys param
  • 计算机内存比外存容量大吗,内存容量一般比外存容量大吗

    大家好 我是时间财富网智能客服时间君 上述问题将由我为大家进行解答 内存容量一般比外存容量大 计算机的内存容量通常是指随机存储器 RAM 的容量 是内存条的关键性参数 内存容量以MB作为单位 可以简写为M 内存的容量一般都是2的整次方倍 比
  • qt qmake 生成的makefile介绍

    参考 概述 跟我一起写Makefile 1 0 文档 NMAKE参考之五 Makefile中的命令 nmake在指定目录下生成 XanaduT的博客 CSDN博客 NMAKE Reference Microsoft Learn 目录 序 m
  • ARM基础--指令集汇编常用指令

    目录 简单的ARM程序 ARM指令集的分类 ARM数据处理指令 ARM跳转指令 ARM的Load Srore指令 ARM的状态寄存器传送指令 ARM软中断指令 ARM伪指令 ARM混合编程 简单的ARM程序 text 表示当前为代码段 gl
  • 拯救者笔记本ubuntu亮度调节

    终端 nvidia settings 点击 DP 2 点击右侧 Color Correction 调节 Brightness即可
  • centos7 arm内核配置yum源

    yum配置文件替换 一 cd到目录 etc yum repos d 创建 替换下面三个文件 1 CentOS Base repo CentOS Base repo The mirror system uses the connecting
  • Java中常用API和标准类的使用与优化

    目录 一 API和Java API简介 二 Object类的重要性 三 Objects工具类的使用 四 标准类的设计与使用 五 String类的特点和常用方法 六 API查找文档及其方法和技巧 一 API和Java API简介 API是Ap
  • 鸿蒙系统应用开发初体验(一)

    上学时期就对操作系统非常有兴趣 甚至还想自己动手尝试尝试 曾买来一堆关于操作系统的书籍肯 这不 翻出来几年前的博客 动手写简单的嵌入式操作系统https blog csdn net yyz 1987 article details 9901
  • VirtualBox虚拟机安装CentOS7.6后无法ssh远程连接虚拟机

    问题如题所述 安装完 一般都是使用ip addr查看虚拟机IP后通过远程工具来尝试连接 虚拟机IP 然后会发现通过此IP无法连接 解决办法 修改VirtualBox的网络配置 1 查看VirtualBox对应网卡的IP地址 对应的IP为19
  • 【数组】点菜题目描述小木呆去食堂吃中饭,食堂提供的菜比较丰富有n(0<n<=1000)种,各种菜都有一个价格ci(ci>0并且都是整数),但他口袋里只剩下m元钱,他计划买两个不同的菜,请问他有多少

    数组 点菜 题目描述 小木呆去食堂吃中饭 食堂提供的菜比较丰富有n 0
  • MySql修改表名的两种方法

    一 rename rename table 旧表名 to 新表名 rename table mysu to new su 二 alter alter table 旧表名 rename as 新表名 alter table mysu rena
  • Python Crypto.Cipher加密包

    The Crypto Cipher package contains algorithms for protecting the confidentiality of data Crypto Cipher包含保护机密数据的加密算法 Inst
  • copy()及copy.deepcopy()

    在说浅拷贝和深拷贝之前先咱们先看看这张图片 A 1 2 3 4 5 6 B A B 0 S print B print A 可以看到只是修改了B中的值但A中的值也随之改变 可以直接推断出A B的存储位置都在同一个地方 现在上浅拷贝 浅拷贝和
  • pnpm install 安装依赖失败

    在使用 pnpm install pnpm i 遇到了一个报错 在使用 EPERM operation not permitted unlink E pnpm store v3 files 9e 经过咨询和查询 得到解决方案是 键盘 win
  • python-pptx处理替换文本

    python中使用python ppt库操作ppt来替换文本内容 包括图片在前方的 from pptx import Presentation from pptx enum shapes import MSO SHAPE TYPE def
  • Whitted光线追踪

    更详细的内容可以看知乎的这篇文章 这里简要的说了一下几何光学的规则 这里引出了光线追踪 正向 从光源开始 和反向 从眼睛开始 在介绍光线追踪前 先来看一些比较简单的 W h i t t e d
  • 面试题.17.07.婴儿名字--并查集

    LeetCode 面试题 17 07 婴儿名字 每年 政府都会公布一万个最常见的婴儿名字和它们出现的频率 也就是同名婴儿的数量 有些名字有多种拼法 例如 John 和 Jon 本质上是相同的名字 但被当成了两个名字公布出来 给定两个列表 一
  • 二、MySQL底层存储原理与结构

    1 前言 本章目标 了解构成MySQL数据库和InnoDB存储引擎的各种类型的文件 理解InnoDB存储引擎的内存结构和磁盘结构 2 文件 MySQL数据库和InnoDB存储引擎的文件有参数文件 日志文件 socket文件 pid文件 表结