全文基于MySQL的存储引擎作为InnoDB
首先查看SQL如何进入仓库:
这是一个非常简单的更新SQL,它从MySQL Server接收到设置的SQL,并且已经传递了MySQL Server层和InnoDB存储引擎。
在MySQL的“分析要求,实施方案”的过程中,它还与内存操作和磁盘操作以及各种日志的记录混合在一起。
它们的用途是什么?它们之间如何合作?为什么要分层mysql?innodb中的缓冲池是什么?
我们慢慢分析。
为什么MySQL分为服务器层和存储引擎的两层?
这个问题没有给出明确的答案,但并不难以猜测。简而言之,它是为了“解耦”。
服务器层和存储引擎有其自己的职责,劳动力划分很明显。用户可以根据不同的需求使用适当的存储引擎。设计多么好,对吗?
后来的开发还验证了“分层设计”的优势:MySQL的原始存储引擎是自我开发的,它仅支持Myisam的前任ISAM,该引擎仅支持简单的查询,后来又开发了带有SleepyCat的Berkeley DB引擎来支持交易。江山有才华横溢的人,海浪正在向前推进。在不断升级其存储引擎的过程中,MySQL遇到了InnoDB的诞生,InnoDB的功能使MySQL感到压力。
如果我自己的存储引擎无法击中InnoDB,该怎么办?
只需加入!
MySQL选择与InnoDB合作。这正是因为MySQL存储引擎的插头设计,两家公司之间的合作非常顺利。MySQL还发布了4.0版的NNODB和Classic 4.1版本的经典4.1版本。
MySQL合并世界模型也已成为MySQL繁荣发展的重要因素。这使MySQL长期保持强大的竞争力。直到今天,MySQL仍然占据很高的数据库市场份额,仅次于ACE数据库Oracle。
在InnoDB中,有一个非常重要的结构池。
什么是缓冲池?
缓冲池是用于缓存mySQL磁盘数据的内存空间。
为什么要缓存mySQL磁盘数据?
我们使用一个示例来解释,我们首先假设没有缓冲池,用户表中只有一个记录。
如果没有缓冲池,则执行是:
从数字可以看出,每个更新需要从磁盘(1 IO)中进行,并且在修改后需要磁盘(1 IO),即,每个更新需要2个磁盘IO。三个更新需要6个磁盘IO。
使用缓冲池,执行就是这样:
从图中可以看出,只需要在第一个execution.two磁盘IO中将数据从磁盘中获取到缓冲池(1 IO),该磁盘保存了4个磁盘IO,而不是缓冲池。
当然,缓冲池的实际操作过程并不那么简单,有许多特定的实现细节和优化技能。由于空间有限,本文没有详细描述它。
我想表达的是,缓冲池是将磁盘IO转换为内存操作,节省时间并提高效率。
缓冲池提高效率,但存在问题。缓冲池基于内存,一旦关闭电源,内存中的数据就会丢失。
如果缓冲池数据的数据在关闭电源时刷新磁盘的数据还为时不晚,那会丢失吗?
仍然是上述示例。如果三个交易完成,如果年龄= 4尚未刷到磁盘时,则电源突然断开,并且数据将丢失:
想象一下,如果这些丢失的数据是核心用户交易数据,用户可以接受吗?
答案是负面的。
那么InnoDB如何不会丢失数据呢?
今天出现了今天的第一个日志记录。
顾名思义,重做意味着重做,重做日志意味着重新记录。
重做日志如何确保数据不会丢失?
修改后,首先将修改后值记录为磁盘上的重做日志。即使突然断开电源,缓冲池中的数据也会丢失。当调用称为缓冲池的内存效率时,还可以确保数据不会丢失。
我们使用一个示例来解释,我们首先假设没有缓冲池,用户表中只有一个记录。
执行过程如下:
如上所示,在重做日志后,将年龄修改为2后,立即将年龄= 2写入重做日志中。如果此时丢失了电源-OFF内存数据,则可以在调用呼叫时读取重做日志中的数据,以恢复数据并确保不会以这种方式丢失数据。
您可能会问,重做日志文件也在磁盘上,数据文件在磁盘上。它们都是磁盘操作。为什么要打扰?为什么不直接将修改后的数据写入数据文件?
傻瓜,因为重做日志是按磁盘的顺序编写的,所以数据刷磁盘是随机编写的,并且磁盘的顺序比随机写入更有效。
在编写数据然后刷数据之前编写日志的这种机制。有一个高大的专业术语 - 登录记录),将其转换为中文是一个预先编写的日志。
尽管磁盘顺序已经非常有效,但内存操作仍然存在一定的差距。
那么,有没有办法进一步优化它?
答案是肯定的。也就是说,将内存缓冲区添加到重做日志中,即重做日志缓冲区,该日志缓冲区使用此娃娃型方法来进一步提高效率。
重做日志缓冲区如何与刷子合作?
在此问题之前,让我们看一下MySQL Server和操作系统之间的关系:
MySQL Server是一个在操作系统上运行的过程。换句话说,操作系统必须悬挂MySQL,但MySQL挂起操作系统。
因此,mySQL有两种情况:
好的,在了解MySQL Server和操作系统之间的关系之后,让我们看一下REDO LOG的下落机制。REDOLOG的刷牙机制由参数Innodb_flush_log_at_trx_trx_commit控制。该参数具有3个值:
写作可以理解为OS缓存(OS缓存),并且可以将刷子理解为将操作系统中的缓存刷到磁盘。
这三种策略之间的区别,我们分别讨论:
此策略将在提交交易之前每次将数据从重做日志刷到磁盘。从理论上讲,只要磁盘不熄灭,数据就不会丢失。
总而言之,该策略是最低的,但是丢失数据的风险也是最低的。
提交此策略后,它将仅将数据写入重做日志缓冲区,然后让背景线程将重做日志缓冲区中的数据设置为磁盘。
该策略是最有效的,但我们都知道,定时任务之间存在差距,但是如果提交了交易,则背景线程没有时间将重做日志刷到磁盘上。在这一点上,数据的一部分将丢失。
总而言之,此策略是最高的效率,丢失数据的风险最高。
此策略将在提交交易之前将重做日志写入OS CACHE,但不会实时将重做日志刷到磁盘,但每秒都会执行一次磁盘操作。
在这种情况下,如果悬挂了MySQL过程并且不悬挂操作系统,则操作系统仍将将OS缓存刷到磁盘上。数据不会丢失,如下所示:
但是,如果MySQL所在的服务器已挂起,即悬挂操作系统,则将倒空操作系统,并且将丢失数据。如下所示:
因此,这种重做日志刷牙策略是上述两种策略的折扣策略。效率相对较高,丢失数据的风险相对较低。在大多数情况下,建议采用此策略。
总而言之,重做日志的作用用于恢复数据。编写重做日志的过程是磁盘顺序。刷牙策略有三种类型。有Innodb_flush_log_trx_commit参数。推荐的设置为2。
我们都知道InnoDB支持交易,交易可以退回。
如果将交易修改为年龄= 1至年龄= 2,当交易尚未提交时,背景线程将年龄= 2刷到磁盘中。这次,无论是内存还是磁盘,年龄已经变成2。如果交易返回,则在修改之前找不到年龄= 1的年龄,也无法回滚。
那我们该怎么办?
这很简单。修改之前保存前年龄= 1。只需根据商店= 1次滚动时滚动即可。
MySQL确实做到了!该记录之前的数据过程称为记录undo log.undo转化为中文以撤销和回滚,而撤消日志的主要作用是滚动数据。
如何回滚?看下面的图片:
在MySQL修改年龄= 1至年龄= 2之前,年龄= 1存储在撤消日志中。当您需要回滚时,您可以在撤消日志中读取= 1的年龄,然后回滚。
应该注意的是,撤消日志默认值为默认情况下有一个全局表空间。您可以简单地理解撤消日志也记录在MySQL表中。它类似于插入撤消日志并插入通用数据。换句话说,在编写撤消日志的过程中,它也写入重做日志。
撤消日志记录以前的数据以提供回滚的能力。
重做日志在修改后记录数据,这提供了折叠和恢复的能力。
什么是Binlog?
Binlog在修改后记录数据,用于归档。
与重做日志类似,Binlog也有自己的刷牙策略。
因此,问题是,binlog和重做日志是记录修改后的值。两者之间有什么区别?为什么重做日志仍然需要binlog?
首先看两者之间的某些差异:
但老实说,我认为这些差异并不是重做日志无法替换Binlog的原因。MySQL官员可以调整重做日志合并Binlog的能力,但他没有这样做。为什么?
我认为,无重做日志替换Binlog的最大原因是“不必要的”。
你为什么这么说?
首先,已经建立了Binlog的生态。MYSQL高可用性主要取决于Binlog的复制,许多公司的数据分析系统和数据处理系统也是Binlog.replace Binlog来改变生态学的工作。
其次,Binlog不是MySQL的瓶颈。没有必要在没有瓶颈的地方度过时间。
综上所述:
最后,使用图片总结全文的知识点:
这篇文章是一年前写的。我最初觉得这是我不想发布的水文。最近,我很无聊并寄出了它。我希望能帮助那些以动态图片的形式在MySQL中拥有良好基础的朋友。
需要强调的是,由于作者的水平有限,本文只能从头开始详细说明MySQL的几个日志的一般角色。在此过程中省略了许多详细信息,例如“撤消日志”和MVCC.RESAPHIPS的真实实现的详细信息,例如Binlog Buffer的存在,更改缓冲区,例如两个阶段的REDO LOG提交。
如果您有任何疑问,我们可以讨论它。如果您在文章中发现错误,希望您指出,非常感谢!
好吧,今天在这里。
谢谢您的阅读!我是编码器,我们下次见。
最后,请注意我的公共帐户“编码器”,以共同讨论进度~~~~
原始:https://juejin.cn/post/7103539389644406798