MySQL-05-MySQL的日志系统

1-redo log(重做日志)

       在MySQL里也有这个问题,如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程IO成本、查找成本都很高。MySQL里经常说到的WAL技术,WAL的全称是Write-Ahead Logging,它的关键点就是先写日志,再写磁盘。具体来说,当有一条记录需要更新的时候,InnoDB引擎就会先把记录写到redo log里面,并更新内存,这个时候更新就算完成了。同时,InnoDB引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做。InnoDB的redo log是固定大小的,比如可以配置为一组4个文件,每个文件的大小是1GB,那么总共就可以记录4GB的操作。从头开始写,写到末尾就又回到开头循环写,如下面这个图所示。

     write pos是当前记录的位置,一边写一边后移,写到第3号文件末尾后就回到0号文件开头。checkpoint是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。write pos和checkpoint之间的是空着的部分,可以用来记录新的操作。如果write pos追上checkpoint,表示空间用完了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把checkpoint推进一下。有了redo log,InnoDB就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为crash-safe

2-binlog(归档日志)

       MySQL整体来看,其实就有两块:一块是Server层,它主要做的是MySQL功能层面的事情;还有一块是引擎层,负责存储相关的具体事宜。上面说的redo log是InnoDB引擎特有的日志,而Server层也有自己的日志,称为binlog(归档日志)。 最开始MySQL里并没有InnoDB引擎。MySQL自带的引擎是MyISAM,但是MyISAM没有crash-safe的能力,binlog日志只能用于归档。而InnoDB是另一个公司以插件形式引入MySQL的,既然只依靠binlog是没有crash-safe能力的,所以InnoDB使用另外一套日志系统——也就是redo log来实现crash-safe能力。
       这两种日志有以下三点不同。
[1]redo log是InnoDB引擎特有的;binlog是MySQL的Server层实现的,所有引擎都可以使用。 [2]redo log是物理日志,记录的是"在某个数据页上做了什么修改";binlog是逻辑日志,记录的是这个语句的原始逻辑,比如"给ID=2这一行的c字段加1"。
[3]redo log是循环写的,空间固定会用完;binlog是可以追加写入的。"追加写"是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

3-mysql的执行过程日志体现

      比如sql语句:update t1 set c=c+1 where id=2;update语句的执行流程图,图中浅红框表示是在InnoDB内部执行的,黄色框表示是在执行器中执行的。

      将redo log的写入拆成了两个步骤:prepare和commit,这就是"两阶段提交"。 prepare阶段,写binlog ,commit ;当在写binlog之前崩溃时,重启恢复后发现没有commit,回滚。备份恢复,没有binlog ,数据 一致 。当在commit 之前崩溃,重启恢复:虽没有commit,但满足prepare和binlog完整,所以重启后会自动commit。备份:有binlog,数据一致 。

4-两阶段提交

       为什么必须有"两阶段提交"呢?这是为了让两份日志之间的逻辑一致。 我们来说说,为什么日志需要"两阶段提交"。这里不妨用反证法来进行解释。由于redo log和binlog是两个独立的逻辑,如果不用两阶段提交,要么就是先写完redo log再写binlog,或者采用反过来的顺序。我们看看这两种方式会有什么问题。
       仍然用前面的update语句来做例子。假设当前id=2的行,字段c的值是0,再假设执行update语句过程中在写完第一个日志后,第二个日志还没有写完期间发生了crash,会出现什么情况呢? 【1】先写redo log后写binlog。假设在redo log写完,binlog还没有写完的时候,MySQL进程异常重启。由于我们前面说过的,redo log写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行c的值是1。 但是由于binlog没写完就crash了,这时候binlog里面就没有记录这个语句。因此,之后备份日志的时候,存起来的binlog里面就没有这条语句。 然后你会发现,如果需要用这个binlog来恢复临时库的话,由于这个语句的binlog丢失,这个临时库就会少了这一次更新,恢复出来的这一行c的值就是0,与原库的值不同。
【2】先写binlog后写redo log。如果在binlog写完之后crash,由于redo log还没写,崩溃恢复以后这个事务无效,所以这一行c的值是0。但是binlog里面已经记录了"把c从0改成1"这个日志。所以,在之后用binlog来恢复的时候就多了一个事务出来,恢复出来的这一行c的值就是1,与原库的值不同。 redo log用于保证crash-safe能力。innodb_flush_log_at_trx_commit这个参数设置成1的时候,表示每次事务的redo log都直接持久化到磁盘。这个参数我建议你设置成1,这样可以保证MySQL异常重启之后数据不丢失。 sync_binlog这个参数设置成1的时候,表示每次事务的binlog都持久化到磁盘。这个参数我也建议你设置成1,这样可以保证MySQL异常重启之后binlog不丢失。

5-flush

       InnoDB在处理更新语句的时候,只做了写日志这一个磁盘操作。这个日志叫作redo log(重做日志),在更新内存写完redo log后,就返回给客户端,本次更新成功。为了保证数据的一致性和准确性,mysql需要找个时间更新一下硬盘数据,这对应的就是把内存里的数据写入磁盘的过程,术语就是flush当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为"脏页"。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为"干净页"。 什么情况会引发数据库的flush过程呢?
[1]InnoDB的redo log写满了。这时候系统会停止所有更新操作,把checkpoint往前推进,redo log留出空间可以继续写【参考章节1的图】。
[2]系统内存不足。当需要新的内存页,而内存不够用的时候,就要淘汰一些数据页,空出内存给别的数据页使用。如果淘汰的是"脏页",就要先将脏页写到磁盘。
[3]MySQL认为系统"空闲"的时候。
[4]MySQL正常关闭的情况。

       InnoDB的策略是尽量使用内存,因此对于一个长时间运行的库来说,未被使用的页面很少。而当要读入的数据页没有在内存的时候,就必须到缓冲池中申请一个数据页。这时候只能把最久不使用的数据页从内存中淘汰掉:如果要淘汰的是一个干净页,就直接释放出来复用;但如果是脏页呢,就必须将脏页先刷到磁盘,变成干净页后才能复用。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Sui受邀参加Builder DAO举办的LeadUp The Night活动,畅谈Sui与Move语言

LeadUp the Night是一个定期举办的MeetUp活动,由Builder DAO邀请区块链各方项目开发者、VC担任本活动的讲师。这个活动旨在促进区块链技术的发展和应用,让参与者有机会开发创新的区块链应用,探索区块链技术的潜力。 ​​11月30日受BuilderDA…

(六)基于高尔夫优化算法GOA求解无人机三维路径规划研究(MATLAB代码)

一、无人机模型简介: 单个无人机三维路径规划问题及其建模_IT猿手的博客-CSDN博客 参考文献: [1]胡观凯,钟建华,李永正,黎万洪.基于IPSO-GA算法的无人机三维路径规划[J].现代电子技术,2023,46(07):115-120 二、高尔夫优化算法GOA简介 高尔夫优化算法…

【JUC】十八、happens-before先行发生原则

文章目录 1、先行发生原则happens-before2、happens-before总原则3、8条happens-before规则4、案例 1、先行发生原则happens-before 在Java中,Happends-Before本质上是规定了一种可见性, A Happends-Before B,则A发生过的事情对B来说是可见的…

项目设计---网页五子棋

文章目录 一. 项目描述二. 核心技术三. 需求分析概要设计四. 详细设计4.1 实现用户模块4.1.1 约定前后端交互接口4.1.2 实现数据库设计4.1.3 客户端页面展示4.1.4 服务器功能实现 4.2 实现匹配模块4.2.1 约定前后端交互接口4.2.2 客户端页面展示4.2.3 服务器功能实现 4.3 实现对…

内网渗透隧道技术一netsh

隧道技术 百度百科: 网络隧道技术指的是利用一种网络协议来传输另一种网络协议,它主要利用网络隧道协议来实现这种功能。网络隧道技术涉及了三种网络协议,即网络隧道协议、隧道协议下面的承载协议和隧道协议所承载的被承载协议 在网络安全中…

【bug篇】Tomcat一直报错,但是代码没问题

代码都没有问题&#xff0c;就是报404错误&#xff0c;原因竟然是版本不兼容&#xff0c;搞了我好长时间&#xff0c;简直麻了&#xff01;&#xff01;&#xff01; 因为我的Tomcat是11版本的&#xff0c;所以导入的servlet和jsp依赖应该是下面这些&#xff1a; <!-- Serv…

【C语言期末不挂科——指针进阶篇】【上】

C语言进阶篇【上】 文章目录 C语言进阶篇【上】字符指针数组指针数组传参和指针传参  数组传参  一级指针传参  二级指针传参 前言&#xff1a; 我们在指针初阶篇学习了&#xff1a; 1、指针就是个变量&#xff0c;用来存放地址&#xff0c;地址唯一标识一块空间。 2、指…

37.从0到上线三天搭建个人网站(第一天)

点赞收藏加关注&#xff0c;你也能住大别墅&#xff01; 挑战三天搭建个人网站 从0到上线 一、项目的主要功能 1.作为自己在网上的一个工作室。 2.发帖 3.展示个人项目连接 4.介绍自己&#xff08;没准儿还能接点活儿&#xff09; 二、UI风格参考 三、技术选型 1.前端&a…

Flask 实现Token认证机制

在Flask框架中&#xff0c;实现Token认证机制并不是一件复杂的事情。除了使用官方提供的flask_httpauth模块或者第三方模块flask-jwt&#xff0c;我们还可以考虑自己实现一个简易版的Token认证工具。自定义Token认证机制的本质是生成一个令牌&#xff08;Token&#xff09;&…

4.5-容器之间的link

我们在实际项目中可能会有种需求&#xff0c;假如我们有个后台项目&#xff0c;它要访问数据库&#xff0c;比如MySQL&#xff0c;它想要访问数据库&#xff0c;就需要数据库的ip和端口。如果有两个容器&#xff0c;一个容器启动的是数据库的MySQL服务&#xff0c;另一个容器启…

二叉树题目:祖父结点值为偶数的结点和

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;祖父结点值为偶数的结点和 出处&#xff1a;1315. 祖父结点值为偶数的结点和 难度 5 级 题目描述 要求 给定二…

13:kotlin类和对象 -- 属性(Properties)

定义属性 类属性可使用var和val定义 class Address {var name: String "Holmes, Sherlock"var street: String "Baker"var city: String "London"var state: String? nullvar zip: String "123456" }属性使用 fun copyAddres…