IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> MySQL如何保证数据不丢失? -> 正文阅读

[大数据]MySQL如何保证数据不丢失?

MySQL作为为现下最流行的开源数据库之一,其中一个重要的原因就是其能保证数据的可靠性,即可以保证数据不丢失。本文对MySQL保证数据不丢失的原理知识进行了总结。本文的内容都是在MySQL的innodb引擎下的原理

1.一条sql语句在MySQL中的执行过程

理解MySQL数据不丢失原理首先要理解一条sql语句在MySQL中是如何执行的。

总体上,MySQL的逻辑架构可以分为Server层和存储引擎两层。

Server层的主要负责处理MySQL的核心服务功能,以及一些内置函数处理等等。

存储引擎层则主要负责数据的存储和提取。支持多种存储引擎。比如最常用的InnoDB。

sql语句大致可以分为两种,查询语句和更新语句。

(1)查询语句执行过程:

其大致流程如下图所示:

流程:

Step1 :客户端与MySQL进行连接,负责这个功能就是Server层的连接器。这一步主要做的是验证客户端的身份,权限等。

Step2:查询缓存,即从缓存中看看这个语句之前是不是执行过,如果执行过,且缓存中有数据,则直接返回数据给客户端。(MySQL8.0以上版本不支持查询缓存,MySQL8.0版本以上可以认为没有这个步骤,缓存技术一般由非关系数据库实现,比如redis,不应该是数据库考虑的)

Step3:没有命中缓存,则分析语句,准备开始执行,sql是与数据库沟通用的语言,分析器就是解析sql语言,明白客户端需要什么数据。当然,这里也有可能sql存在语法错误,出现语法错误则返回语法错误信息。

Step4:经过分析器,则可以认为MySQL已经了解客户端需要查询的内容,这个时候进入优化器,优化器的作用就是为选择合适查询方式。(比如:走哪个索引合适,连接表的顺序等等优化操作)。

Step5:语句进入执行阶段,调用存储引擎查询数据(这个过程还会再核对一次当前客户端的权限,如果对该表没有查询权限,就会返回错误信息),引擎将查询出来的结果组成结果集返回给客户端。

(2)更新语句执行流程:

更新语句执行流程其实与查询语句执行流程差不多,因为更新过程一样要先定位到该数据,这个过程就和查询语句的流程是差不多,依次需要经过连接器->分析器->优化器->执行器->存储引擎找到该数据项,然后更新。与查询流程最大的不同的地方就是,更新过程中涉及到两个日志模块,分别是重做日志(redo log)和归档日志(binlog)。这两个日志模块是MySQL保证数据不丢失的重要模块。

2.重做日志(redo log)

每次更新操作如果都要直接写进磁盘中,则每一次的更新操作都要先到磁盘找到该行数据,然后进行更新,操作磁盘则就涉及到IO操作,每个更新操作都要进行IO操作成本将很大。所以MySQL引入了redo log来提升更新效率。即WAL(Write-Ahead Logging)技术,其核心就在于每次更新操作都是先写日志,等空闲或者redolog写不下的时候再去更新磁盘。

即有了redolog后,更新流程变为,每次更新操作,将记录写在redolog中,并更新内存中的数据,然后直接返回修改成功。然后到合适的时候将redolog中的内容更新到磁盘中。(这样做将极大的提高更新的效率,客户端可以在较短的时间内得到反馈,而且存储引擎不再需要为每一次的更新操作都进行IO操作,可以存到一定的“量”,然后再刷新进磁盘里)。

redolog是固定大小的,写完则重头开始写,MySQL通过两个指针来控制redolog中的内容,分别是checkPoint(当前更新进磁盘的位置),writePoint(当前已经写到的位置),两个指针右移到末尾则又重新开始(checkPoint将指向的内容刷新进磁盘并右移,writePoint将新的更新操作写入并右移),显然,writePoint和checkPoint之间的位置就是可写位置,如果writePoint == checkPoint,说明redolog满了,这个时候就需要停下来将redolog中的内容刷新进磁盘里(这个时候MySQL的更新操作会变慢),让checkPoint向右移动,从而“腾出位置”继续写。

redolog的存在不仅提高了更新的效率,还保证数据的不丢失,如果MySQL发生异常重启,则可以加载redolog文件恢复数据。

3.归档日志(binlog)

binlog是Server层的日志文件,binlog与redolog,都是用来记录对数据做了什么修改,,但是有一定的区别:

记录的内容上:redolog是物理日志,记录的是具体在哪一个数据页(数据页是MySQL中磁盘和内存交换的基本单位,也是MySQL管理存储空间的基本单位,可以理解为一个数据页中有多行数据)做了什么修改,而binlog记录的更新语句的原始逻辑,比如在id=XXX的a字段上+1.

记录方式上:redolog是循环写,有固定的大小,binlog是追加写,一个文件用完切换到下一个,不会覆盖之前的数据。

实现的位置:redolog是存储引擎层实现的(innodb特有的一种日志),binlog是server层的日志,所有引擎都具有。

整合两个日志,重新梳理一下更新过程:

step1:建立连接(连接器)

step2:分析sql(分析器)

step3:优化过程,选择合适的索引来定位数据等等(优化器)

step4:调用引擎层接口去拿数据(执行器)

step5:存储引擎找到这一行,如果这一行所在的数据页就在内存中,直接返回这行数据,没有则从磁盘中读入内存,然后返回。

step6:执行器拿到数据,对该数据进行对应的修改,得到一行新的数据,然后调用引擎接口写入这行新数据。

step7:存储引擎直接将数据更新在内存中,并将这个操作更新到redolog中,redolog此时处于prepare状态。然后直接返回,表明随时可以提交。

step8:执行器将这个操作更新到binlog中,并更新进磁盘。

step9:执行器再次调用引擎接口,让引擎将刚刚的更新操作进行提交(redolog改成commit状态),整个更新过程完成。

为什么这样就能保证数据不丢失呢?或者说为什么redolog要分为prepare和commit两个状态(即两阶段提交)?

首先,如果redolog不分两个阶段,直接在step7直接提交,那么假如MySQL在执行step8的时候发生异常重启,则恢复过来后,这个更新操作是再redolog中是已提交的,则这个修改是最终会成功刷新进磁盘的,但是binlog中没有对应的记录,这将导致如果要使用binlog将数据库回退到某一个时刻的时候,“漏”了一条sql更新记录而导致数据回退的与那个时刻并不一致,或者做主从一致(通过binlog实现主从一致)时,从库从主库中拿到的binlog是“少”了一条sql记录的,这将导致主从数据不一致。(其实可以直接理解为binlog没有记录MySQL中的所有更新操作本身就是违背了binlog的设计的初衷)。

其次,如果先提交binlog也是不行的,如果先提交了binlog,再提交了redolog,提交redolog过程中发生异常重启,redolog中的数据没有提交从而丢失,则binlog则是“多”了一条数据操作。

但是如果是两阶段提交则能有效规避这些问题,比如step8中binlog提交过程发生异常,则redolog中记录的是出于prepare状态的,等MySQL恢复过来时,则认为这次更新是失败的,则会自动回滚这次操作。这样binlog中更新记录与数据库中的数据是可以对应上的。

最后,MySQL保证了binlog和redolog中的数据更新记录与真实数据操作是一致的,就可以保证数据不丢失(所有的更新操作都记录了,可以恢复到任意时刻),在做主从备份或者数据库备份时往往都是依靠binlog进行,所以关键便在于保证binlog的数据与数据库操作保持一致。(MySQL在保证数据不丢失上还有很多细节,这将在后续继续总结)。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-05-12 16:31:26  更:2022-05-12 16:33:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/29 12:46:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码