MySQL Innodb引擎

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 介绍MySQL Innodb相关知识

1、InnoDB的重要内存结构--缓存池

Innodb存储引擎中有一个非常重要对吧放在内存里的组件,就是缓存池(Buffer Pool),这里面会缓存很多的数据,以便于在后续查询的时候,如果这个数据已经在缓存池里面了,就可以不用去查询磁盘了,直接在内存中获取或者修改数据,避免频繁的IO。

2、如何让你更新的数据可以回滚--undo日志文件

如果我们更新了一条数据,如果这次更新是在一个事务里面的,那么这次更新在事务提交之前,我们是可以回滚这个事务的,也就是我们可以把数据在回滚回去,那这是怎么做到的呢?


Innodb存储引擎引入了一个undo日志文件,负责数据的回滚。在更新一条数据之前,会将原始数据先写入undo日志之中,如果我们要回滚事务,这需要从undo日志中拿出旧值覆盖即可。

image.png

3、万一系统宕机,如何避免数据丢失--Redo Log Buffer

我们知道,我们更新数据是在内存中的,这时候数据还没有进入磁盘之中,那么如果这时候我们的MySQL宕机了,内存中的数据比如会丢失,那怎么解决呢?


Innodb存储引擎为了解决这个问题,引入了一个新的内存结构Redo Log Buffer,在我们修改数据的时候,就必须把对内存所做的修改写入到Redo Log Buffer里面去,但是这个Redo Log Buffer还是在内存中的,如果这时候我们还没有提交事务,MySQL却突然宕机,必然会导致内存里Buffer Pool中的修改过的数据都丢失,同时写入Redo Log Buffer里面的数据肯定也会丢失,但是这种时候时候即使MySQL宕机数据丢失,也是没有关系的,因为我们的事务还没提交,也就是表示这个操作还没有执行成功,就算内存数据丢失了,磁盘数据也不会变化,你的执行也没有成功。 但是如果这时候事务已经提交了,我们的执行已经成功了,但是这时候MySQL却宕机了,那这时候肯定是不行的,毕竟我们都执行成功了,你不能说数据没了就没了。那怎么办呢?


那么我们可以想到,为了防止数据丢失,我们肯定要将数据持久化,也就是肯定要写入磁盘。 Innodb存储引擎确实也是这么做的,当我们想要提交一个事务的时候,会根据一个策略把redo日志从Redo Log Buffer里面写入到磁盘文件里面去,这样我们就可以保证即使MySQL宕机了,至少操作记录还是存在的,不会丢失,那么这个策略是什么呢?


这个策略通过innodb_flush_log_at_trx_commit参数来配置的,它有这么几个策略。 如果这个值为 0 ,那么提交事务的时候,不会把Redo Log Buffer里的数据刷入磁盘文件,此时如果事务已经提交了,MySQL却宕机了,那么你的数据妥妥的就没了,就可以考虑跑路了。 当这个值为 1 ,那么提交事务的时候,就必须把Redo Log Buffer从内存刷入到磁盘之中,只要事务提交成功了,那么就可以保证Redo Log一定已经在磁盘之中了,这时候就是MySQL宕机了,那么数据也不会丢。 当这个值为 2 ,那么提交事务的时候,会把Redo Log Buffer里面的数据写入磁盘对应的OS Cache里去,而不是直接进入磁盘,可能要1秒之后才会把OS Cache里面的数据写入到磁盘文件里面去,这时候就算MySQL宕机了,那么数据是不会丢失的,但是(凡是就怕但是),如果这时候连MySQL所在的这台机器也宕机了,那么数据还是妥妥的就丢了。


所以对应MySQL这种需要保持强一致性的引用,一定要保持这个参数的值为 1 ,保证不管是MySQL、还是机器挂了、至少数据不会丢失,也不用跑路。

4、Mysql binlog到底是什么

实际上我们上面说过的redo log,它是一种偏向物理性质的重做日志,因为它里面记录的是类似与这样的东西,“对哪个数据页中的什么记录,做了什么修改”;而且redo log本身是属于InnoDB存储引擎特有的一个东西。


而binlog叫做归档日志,它里记录的是偏向逻辑性的日志,类似与“对users表中的id=10这一行数据做了更新操作,更新以后的值是什么”。binlog不是innodb存储引擎特有的日志文件,是属于mysql server自己的日志文件。

5、提交事务的时候,同时会写入binlog

在我们提交事务的时候,会把redo log日志刷入磁盘,然后同时还会把这次更新对应的binlog日志写入到磁盘里面去。

6、binlog日志的刷盘策略

既然redo log有不同的刷盘策略,那么binlog肯定也有,binlog的刷盘策略通过sync_binlog参数进行控制,它有两个取值,分别为0和1。


sync_binlog=0,这个是其默认值,此时会将binlog先写入os cache里面去,然后经过一段时间之后再将其写入到磁盘上面去。这时候如果机器宕机,那么数据就会丢失。


sysc_binlog=1,此时在提交事务的时候,会强制把binlog直接写入到磁盘文件里面去,这样提交事务之后,就算机器宕机,磁盘上面的binlog日志也是不会丢失的。

7.基于binlog和redo log完成事务的提交

当我们把binlog写入到磁盘文件之后,接着就会完成最终的事务提交,此时会把本次更新对应的binlog文件名称和这次更新的binlog日志在文件里的位置,都写入到redo log日志文件里面去,同时在redo log日志文件里写入一个commit标记,在做完这个事情之后,才算最终完成了事务的提交。

8、最后一步在redo日志中写入commit标记的意义是什么?

commit标记用来保持redo log日志与binlog日志一致。 例如:假设提交事务的时候,必须要完成上面的5、6、7三个步骤,才算是提交了事务,那么如果有步骤没有完成会怎么样呢? 加入我们完成了步骤5的时候,也就是redo log刚刷入磁盘之后,MySQL就宕机了,这个时候因为没有最终的commit标记在redo日志里,所以此次事务可以判定不成功,不会因为redo日志文件里有这次更新的日志,但是binlog日志文件里没有这次更新的日志,不会出现日志不一致的问题。


如果完成了步骤6,redo log日志和binlog日志全都落盘了, 此时MySQL宕机了,那么因为redo log文件里面没有commit标记,因此这次事务提交也是失败的。


必须是在redo loh中写入最终的事务commit标记,然后此时事务提交成功,而且redo log里有本次更新对应发日志,binlog里面也有这次更新对应的日志,redo log和binlog完全是一致的。

9、后台IO先随机将内存更新后的脏数据刷入磁盘

在日志成功提交之后,我们的数据还是存在于内存之中(Buffer Pool),按这些数据肯定是要落盘的,这样才不会丢失,那么这个数据什么进入磁盘里面呢?


MySQL里面有一个后台的IO线程,会在某个时间里,随机的把内存Buffer Pool中的修改后的脏数据给刷回的磁盘上的数据文件里面去。


就算在刷盘之前mysql崩了或者机器崩了,也没关系,因为重启之后,会根据redo日志恢复之前提交事务做过的修改更新到内存里面去,然后等适当时机,IO线程再把这个修改后的数刷入到磁盘里面去。

10、总结

大家通过一次更新数据的流程,就可以清晰地看到,InnoDB存储引擎主要就是包含了一些buffer pool、redo log buffer等内存里的缓存数据,同时还包含了一些undo日志文件,redo日志文件等东西,同时mysql server自己还有binlog日志文件。


在你执行更新的时候,每条SQL语句,都会对应修改buffer pool里的缓存数据、写undo日志、写redo log buffer几个步骤;


但是当你提交事务的时候,一定会把redo log刷入磁盘,binlog刷入磁盘,完成redo log中的事务commit标记;最后后台的IO线程会随机的把buffer pool里的脏数据刷入磁盘里去。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
22小时前
|
运维 负载均衡 关系型数据库
MySQL高可用解决方案演进:从主从复制到InnoDB Cluster架构
MySQL高可用解决方案演进:从主从复制到InnoDB Cluster架构
|
1天前
|
存储 SQL 关系型数据库
mysql中MyISAM和InnoDB的区别是什么
mysql中MyISAM和InnoDB的区别是什么
9 0
|
7天前
|
存储 关系型数据库 MySQL
【MySQL系列笔记】InnoDB引擎-数据存储结构
InnoDB 存储引擎是MySQL的默认存储引擎,是事务安全的MySQL存储引擎。该存储引擎是第一个完整ACID事务的MySQL存储引擎,其特点是行锁设计、支持MVCC、支持外键、提供一致性非锁定读,同时被设计用来最有效地利用以及使用内存和 CPU。因此很有必要学习下InnoDB存储引擎,它的很多架构设计思路都可以应用到我们的应用系统设计中。
91 4
|
11天前
|
存储 监控 关系型数据库
【MySQL】InnoDB 什么情况下会产生死锁
【MySQL】InnoDB 什么情况下会产生死锁
|
13天前
|
SQL 关系型数据库 MySQL
|
2月前
|
关系型数据库 MySQL 数据库
MySQL谈谈InnoDB怎么解决幻读的
MySQL谈谈InnoDB怎么解决幻读的
21 2
|
2月前
|
存储 关系型数据库 MySQL
MySQL InnoDB数据存储结构
MySQL InnoDB数据存储结构
|
2月前
|
存储 缓存 关系型数据库
MySQL的varchar水真的太深了——InnoDB记录存储结构
varchar(M) 能存多少个字符,为什么提示最大16383?innodb怎么知道varchar真正有多长?记录为NULL,innodb如何处理?某个列数据占用的字节数非常多怎么办?影响每行实际可用空间的因素有哪些?本篇围绕innodb默认行格式dynamic来说说原理。
840 6
MySQL的varchar水真的太深了——InnoDB记录存储结构
|
3月前
|
存储 缓存 关系型数据库
MySQL - 存储引擎MyISAM和Innodb
MySQL - 存储引擎MyISAM和Innodb
|
27天前
|
存储 关系型数据库 MySQL
MySQL引擎对决:深入解析MyISAM和InnoDB的区别
MySQL引擎对决:深入解析MyISAM和InnoDB的区别
36 0