mysql详解之innoDB

news2024/11/17 3:24:37

索引

Mysql由索引组织,所以索引是mysql多重要概念之一。

聚簇索引

InnoDB和MyISAm一样都是采用B+树结构,但不同点在于InnoDB是聚簇索引(或聚集索引),将数据行直接放在叶子节点后面。

这里可能存在一个误区:觉得MyISAm是B树。innoDB采用了B+树,将数据存在了叶子节点上。
这个逻辑是不对的。这两个存储引擎都采用的B+树,只是叶子节点上存的数据不一样。MyISAm存的是一个地址,而innoDB存的一整行数据。

聚簇索引是innoDB的主键索引的实现方式。如果没有设置主键呢?难道就没有聚簇索引了?当然不会了,你不创建,innoDB会帮你找一个:

  1. 首先看看是不是有唯一索引,如果有的话,那么第一个唯一索引就是聚簇索引

  2. 如果唯一索引也没有,表结构中还藏了一个隐藏字段(DB_ROW_ID)作为聚簇索引字段。

如图所示:
在这里插入图片描述

辅助索引(二级索引)

非聚簇索引都是辅助索引,包括唯一索引,普通索引,组合索引。

之所以叫辅助索引,是因为一般情况下都需要“回表”,最终还是要靠聚簇索引查出数据。

select * from tab where name = 'a';

如图
在这里插入图片描述

索引分裂

当新增/修改索引数据时,索引块空间不够,分裂出一个新的索引块过程成为索引分裂。分裂方式方式包括:
在这里插入图片描述

1-9分裂:传统分裂方式。一块索引写完,加一块新的,上一个索引块数据尽量不动。适合索引自增长,事务并发比较低的情况。但可能引起索引块层级突然升高多层的问题。

5-5分裂:新增索引块时,把上一个索引块一半的数据分到新索引块中。保证了增加了B+树层级的稳定性(避免增加一个索引块,增加两层以上的情况)。适合随机索引数据,事务并发高的情况。但会引起索引的空间利用率不高的问题。

buffer poor(缓冲池)

数据库的读操作,并不是直接从磁盘读取数据。而是首先在buffer poor里找,如果有就直接返回,没有再去磁盘获取,放在buffer poor里,然后返回。听起来像缓存,但其实不是。

mysql缓存是[sql语句-查询结果]的key-value数据(由于命中效率不高,在mysql8就去掉了这块功能),属于mysql的server层。
buffer poor里单纯是数据,是存储引擎的一部分。

数据库的写操作,并不是直接改的磁盘文件,而是拿到缓冲池操作。从这个角度,缓冲池起到一个工作空间的作用。修改过的数据页称为脏数据页。等待被刷到磁盘(在刷到磁盘之前先写到redo log中)。

可以通过调整 innodb_buffer_pool_size 参数来设置 Buffer Pool 的大小。

表空间

表空间(tablespace)是mysql数据在磁盘上的存储形式。或者说是.ibd文件的数据格式。表空间的逻辑,从大到小依次可拆分为:段(segment),区(extent),页(page),行(Row)。如下图所示
在这里插入图片描述
一般把页作为基本单位。

事务

innoDB为实现事务,引入了一系列技术,同时也带来了很多问题,为解决这些问题,又引入更多新技术。

所以mysql没有一开始就给自己默认存储引擎加入事务,也是可以理解的。

事务四大特性

如图所示
在这里插入图片描述

Mysql是一个多线程系统,要实现事务,保证数据库的一致性,锁是必要的技术。
在这里插入图片描述

日志

redo log

redo log称为重做日志,用于记录事务操作。以便在服务重启后,通过前滚操作,恢复数据。保证事务在服务正常/异常重启的情况下依然能保障原子性。

有些文章会这么做比喻:

redo log可以理解为饭店里的小黑板。饭店允许客人记账赊账。当就餐人太多时,就先把钱记到小黑板上。这样就不用在忙的焦头烂额时还去翻账本,去记账算账了。
或者
redo log 就像快递代收点,往一家一家送快递,太慢,先统一摆到代收点。有时间再往用户家里送。

从某种程度上说,这么比喻也没问题。但可能会让人产生误解:redo log在起“缓冲”作用?那么下一步是不是:把数据从redo log再往数据文件挪?

如果你这么想,那就可能就被误导了。

redo log和数据写入数据库表文件。正常情况下,两者并没有很强的关联性。你写你的日志,我写我的数据。只有当服务异常重启(断电/服务宕机),redo log才开始起作用。为数据库恢复缺失的数据。如图所示
在这里插入图片描述

上图中,左边是redo log buffer写到磁盘日志文件的过程。右边是buffer poor写入磁盘数据库文件的过程。左右两边在正常情况下,并没有什么交集。恢复过程是服务重启时才会起作用。

当然,但也不是完全没关联。redo log在正常情况下并不完全只会无脑记日志。它还起到一个很重要的作用:纪录完后,作为事务完成的标志。有时候甚至会说:日志比数据更重要

顺序io:由于日志的顺序io的特性,redo log可以实现快速的落盘操作(相比右边的数据落盘要快的多,因为右边要处理复杂的数据结构,写磁盘相当于一种随机io)。
前面说的两个比喻,其实想表达的就是这层意思。

上图中,直接从log buffer 刷到了磁盘。实际操作中其实中间还有一层OS Buffer(操作系统的内核空间),如图所示
在这里插入图片描述

注意看这个图,虽然也是两条路,但是redo log和 undo log。其实看到这里就会明白一件事:无论是redo log,undo log还是buffer pool里的数据都需要经过 buffer(用户空间) --> os buffer(操作系统内核空间) --> file(磁盘文件)

这里涉及到一个配置参数innodb_flush_log_at_trx_commit
这个值表示三种从内核刷到磁盘的刷盘策略:

1:【默认】事务每次提交都会将log buffer中的日志写入os buffer并调用fsync()刷到log file on disk中。这种方式即使系统崩溃也不会丢失任何数据,但是因为每次提交都写入磁盘,IO的性能较差。

0:事务提交时不会将log buffer中日志写入到os buffer,而是每秒写入os buffer并调用fsync()写入到log file on disk中。也就是说设置为0时是(大约)每秒刷新写入到磁盘中的,当系统崩溃,会丢失1秒钟的数据。

2:每次提交都仅写入到os buffer,然后是每秒调用fsync()将os buffer中的日志写入到log file on disk。

在《Mysql技术内幕》里,作者做了一个实验50万数据的插入测试,配置从1改为0,时间从113秒 缩短到了 13.9秒,近10倍的速度差距,还是很可观的。如果业务以写数据为主(如状态监控系统),并发量不是很大,不在乎可能丢失1秒到数据,我个人认为调为0就行。

前面我们看到有两个redo log日志(ib_logfile0, ib_logfile1),其实以后也不会再增加了。因为redo log是循环写数据。新数据会把最老的数据逐渐覆盖。这个日志本来就是为了拯救系统宕机前最后一批事务。而是不是用来恢复长期数据的。

与之对应的时binlog,有人叫它二进制日志,这纯粹是直译。其实redo log,binlog,undo log 都不是纯文本日志。有人称之为”归档日志“,这个在意思上就很贴切。

redo log和binlog的同步

redo log是innoDB用来保障数据完整性的日志。binlog是Mysql自带的日志,除了可以用来恢复数据,还用于集群之间的数据同步。所以这两者必须保证一致性。否则数据库集群之间的数据就不一致了。innoDB采用了2阶段提交机制:
在这里插入图片描述
先把redo log写完,但不改状态。再去写binlog,等binlog写完,再改状态。

实际生产中,在1~6处都可能出现中断。前四处中断都无所谓,二者都可以保持”未提交“状态。但问题是如果在5或者6处中断就有问题了。此时binlog完全可能已经把数据同步给集群的其他数据库了。但redo log却还是prepare状态。这就会导致本机和其他服务器数据不一致。因为2pc在理论上就无法实现一致性。

但好在日志是可以自我校验完整性的,无论是redo log还是binlog都可以。

所以当服务再次重启,redo log着手恢复数据时,如果发现最后一个事物的状态是”prepare“状态。它并不会马上把该事务数据删掉,而是要再去binlog那里看看。如果binglog的这个事务是完整的,那么就可以判断应该就是刚好在5或6的位置中断的。则把事务数据恢复后状态改为commit,这样本机和其他服务器数据就一致了。实现了弥补2pc逻辑漏洞的问题。

当然,由于5,6时间极短。6这一步,只是改一改状态,几乎不费什么时间。前面大家都把事情干完了,最后只是为了一起确认个状态。这也是为什么2pc机制即便存在逻辑漏洞,但依然被使用的原因。

redo log还有一个特性需要强调的是,它是物理日志。经常会以此和undo log一起说,或者跟binlog做对比。因为undo log和binlog都是逻辑日志。具体见博客mysql详解之redolog的关键——幂等性

redo log所在位置(mac系统的目录)
在这里插入图片描述

undo log

被称为回滚日志。可以在事务出现异常(非服务或服务器异常)时进行回滚操作。也就是程序正常的回滚操作。

和redo log的物理日志不同,undo log是逻辑日志。可以简单理解为sql语句。

当用户执行了insert语句,那么就会生成delete的undo log日志。当用户执行了a --> b的updte语句,那么就会生成一个b --> a的undo log日志。

undo log和redo log 共同实现了:无论是日常事务回滚还是服务重启,都可以自动保障事务的原子性。

undo log的第二大作用在是MVCC机制中实现多版本控制。MVCC中多个版本的数据,其实只有一个版本。修改就是在原数据上改的(都是buffer pool里的操作)。之所以看起来还能查到“历史版本”。不是保留了历史版本,而是通过undo log回退计算获得的历史版本。

另外,undo log也会产生redo log,因为undo log也要实现持久性保护。

undo log默认和redo log存放在一起,也可以通过配置改为和表文件存放在一起。

参考

深入理解MySQL重做日志 redo log
MySQL事务日志(redo log和undo log)的详细分析【非常全面】
B树索引是怎么分裂的
Mysql buffer pool详解
答应我,这次要搞懂 Buffer Pool
MySQL的表空间是什么
为什么MySQL 删除表数据 磁盘空间还一直被占用
mysql深入浅出之日志(redolog, binlog, undolog)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/354723.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C语言】编程初学者入门训练(14)

文章目录131. kiki学结构体和指针132. kiki定义电子日历类133. 圣诞树134. 超级圣诞树131. kiki学结构体和指针 问题描述:KiKi学习了结构体和指针,他了解了结构体类型可以定义包含多个不同类型成员,而指针本质是内存地址,是引用数…

【人脸检测】Yolov5Face:优秀的one-stage人脸检测算法

论文题目:《YOLO5Face: Why Reinventing a Face Detector》 论文地址:https://arxiv.org/pdf/2105.12931.pdf 代码地址:https://github.com/deepcam-cn/yolov5-face 1.简介 近年来,CNN在人脸检测方面已经得到广泛的应用。但是许多…

【C++的OpenCV】第一课-opencv的间接和安装(Linux环境下)

第一课-目录一、基本介绍1.1 官网1.2 git源码1.3 介绍二、OpenCV的相关部署工作2.1 Linux平台下部署OpenCV一、基本介绍 1.1 官网 opencv官网 注意:官网为英文版本,可以使用浏览器自带的翻译插件进行翻译,真心不推荐大家去看别人翻译的&am…

过滤器和监听器

1、过滤器Filter 作用是防止SQL注入、参数过滤、防止页面攻击、空参数矫正、Token校验、Session验证、点击率统计等等; 使用Filter的步骤 新建类,实现Filter抽象类;重写init、doFilter、destroy方法;在SpringBoot入口中添加注解…

演示Ansible中的角色使用方法(ansible roles)

文章目录一、ansible 角色简介二、roles目录结构三、role存放的路径:配置文件ansible.cfg中定义四、创建目录结构五、playbook中使用rolesplaybook变量会覆盖roles中的定义变量六、控制任务执行顺序七、ansible—galaxy命令工具八、安装选择的角色1.从网上下载&…

使用vue3,vite,less,flask,python从零开始学习硅谷外卖(41-82集)

第41集:这里遇到个大坑,因为这种项目有很多页面,有时候有的页面忘了保存就会出错,还很难排查,浪费了我快半天的时间。可以把vscode的代码自动保存打开,以后就不会踩坑了。 第42集:没啥好说的。 …

判断字符串中的字符的类型isdecimal();isalpha();isdigit();isalnum()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 判断字符串中的字符的类型 isdecimal();isalpha();isdigit();isalnum() [太阳]选择题 对于代码中isdecimal()和isalnum()输出的结果是? s "ABc123&…

亿级高并发电商项目-- 实战篇 --万达商城项目 十一(编写商品搜索功能、操作商品同步到ES、安装RabbitMQ与Erlang,配置监听队列与消息队列)

👏作者简介:大家好,我是小童,Java开发工程师,CSDN博客博主,Java领域新星创作者 📕系列专栏:前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 &#x1f4…

Sandboxie-沙箱软件-Plus版本(Qt)-主框架程序-SandMan.exe-创建语言文件-tr-Qt-语言国际化

文章目录1.功能介绍2.Qt语言国际化3.设置软件的语言版本4.作者答疑1.功能介绍 沙箱软件的增强版本采用Qt架构开发,核心模块与经典版本相同,本文主要介绍SandMan.exe这个主程序代码。在main.cpp这个入口函数里,有主窗口入口,如下所…

2.5|iot冯|方元-嵌入式linux系统开发入门|2.13+2.18

一、 Linux 指令操作题(共5题(共 20 分,每小题 4分)与系统工作、系统状态、工作目录、文件、目录、打包压缩与搜索等主题相关。1.文件1.1文件属性1.2文件类型属性字段的第1个字符表示文件类型,后9个字符中,…

【物联网】智慧农业病虫害精准辨识竞赛思路及代码分享

来源:投稿 作者:LSC 编辑:学姐 比赛官网: https://www.dataglobal.cn/cmpt/signUpInfo200.html 任务描述 请参赛者设计智慧农业病虫害检测系统,给出一体化问题解决方案,鼓励参赛选手结合某一果园/农作物实际情况建立…

使用 URLSearchParams 解析和管理URL query参数

介绍 首先 URLSearchParams是一个构造函数,会生成一个URLSearchParams对象,参数类型: 不传 | string | object | URLSearchParams, 并且遇到特殊字符它会自动帮我们encode 和 decode const ur…

Java模块化概述

3 模块化 3.1 模块化概述 Java语言随着这些年的发展已经成为了一]影响深远的编程语言,无数平台,系统都采用Java语言编写。但是,伴随着发展,Java也越来越庞大,逐渐发展成为-门“臃肿” 的语言。而且,无论是运行个大型的…

Vulnhub 渗透练习(五)—— lazysysadmin1

环境搭建 下载链接 vmware 打开靶机,nat 网络适配,攻击机同样。 信息收集 一个一个的看过去,这边就不贴图了。 漏洞挖掘 用 kail 的 wpscan 扫一下 wordpress,没发现漏洞。 ┌──(geng㉿geng)-[~] └─$ wpscan --url http…

【Linux06-基础IO】4.5万字的基础IO讲解

前言 本期分享基础IO的知识,主要有: 复习C语言文件操作文件相关的系统调用文件描述符fd理解Linux下一切皆文件缓冲区文件系统软硬链接动静态库的理解和制作动静态编译 博主水平有限,不足之处望请斧正! C语言文件操作 #再谈文件…

SQLSERVER2019安装步骤过程

第一步官网下载SQLSERVER软件包 目前官网只能下载最新版本2022版本。 通过迅雷下载网址 SQL Server 2019 Enterprise (x64) - DVD (Chinese-Simplified)企业版 ed2k://|file|cn_sql_server_2019_enterprise_x64_dvd_2bfe815a.iso|1632086016|58C258FF0F1D006DD3C1F5F17AF3E…

ELK_Elasticsearch环境搭建

目录 一、Windows安装elasticsearch 1、安装JDK 2、下载和解压 3、配置文件 4、启动 5、检查ES是否启动成功 6、浏览器访问 二、 Windows安装Kibana 一、Windows安装elasticsearch 1、安装JDK 安装JDK,至少1.8.0_73以上版本,验证:j…

dbForge Source Control for SQL Server 2.5.X Crack

SQL Server功能概述 的 dbForge 源代码管理 dbForge Source Control for SQL Server 是一个可视化的 SSMS 插件,具有简单易用的界面,可帮助您轻松跟踪 SQL Server 数据库对象中的更改内容、更改时间和原因。该工具使您能够将数据库连接到多个版本控制系统…

【Python学习笔记】40.Python3 SMTP发送邮件

前言 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。 Python3 SMTP发送邮件 python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了…

CSS基础选择器,你认识多少?

前言在上一文初识CSS中,我们了解到了其格式:选择器{ }在初步尝试使用时,我们笼统的直接输入了p { }以选择p标签来对其操作,而这一章节里,我们再进一步探索有关基础选择器的相关内容,理解选择器的作用。选择…