MySQL性能优化(四)redo log实现原理

文章目录

    • 1.redo log的作用
    • 2.redo log的结构
      • 2.1.redo log 记录
      • 2.2.redo log block
      • 2.3.redo log buffer
    • 3.redo log buffer 刷盘

1.redo log的作用

首先我们都知道,执行增删改SQL语句的时候,都是针对一个表中的某些数据去执行的,此时的话,首先必须找到这个表对应的表空间,然后找到表空间对应的磁盘文件,接着从磁盘文件里把你要更新的那批数据所在的数据页从磁盘读取出来,放到Buffer Pool的缓存页里去。

redo log可以保证我们事务提交之后,如果事务中的增删改SQL语句更新的缓存页还没刷到磁盘上去,此时MySQL宕机了,那么MySQL重启过后,就可以把redo log重做一遍,恢复出来事务当时更新的缓存页,然后再把缓存页刷到磁盘就可以了。

redo log本质是保证事务提交之后,修改的数据绝对不会丢失的

那么有人会问了,你事务提交的时候把修改过的缓存页都刷入磁盘,跟你事务提交的时候把你做的修改的redo log都写入日志文件,他们不都是写磁盘么?差别在哪里?

实际上,如果你把修改过的缓存页都刷入磁盘,这首先缓存页一个就是16kb,数据比较大,刷入磁盘比较耗时,而且你可能就修改了缓存页里的几个字节的数据,难道也把完整的缓存页刷入磁盘吗?而且你缓存页刷入磁盘是随机写磁盘,性能是很差的,因为他一个缓存页对应的位置可能在磁盘文件的一个随机位置,比如偏移量为45336这个地方。

但是如果是写redo log,第一个一行redo log可能就占据几十个字节,就包含表空间好、数据页号、磁盘文件偏移量、更新值,这个写入磁盘速度很快。此外,redo log写日志,是顺序写入磁盘文件,每次都是追加到磁盘文件末尾去,速度也是很快的。所以你提交事务的时候,用redo log的形式记录下来你做的修改,性能会远远超过刷缓存页的方式,这也可以让你的数据库的并发能力更强。

2.redo log的结构

2.1.redo log 记录

redo log里本质上记录的就是在对某个表空间的某个数据页的某个偏移量的地方修改了几个字节的值,具体修改的值是什么,他里面需要记录的就是:
日志类型,表空间ID,数据页号,数据页中的偏移量,具体修改的数据

一条redo log中依次排列上述的一些东西,这条redo log表达的语义就很明确了,他的类型是什么,类型就告诉了你他这次增删改操作修改了多少字节的数据;然后在哪个表空间里操作的,这个就是跟你SQL在哪个表里执行的是对应的;接着就是在这个表空间的哪个数据页里执行的,在数据页的哪个偏移量开始执行的,具体更新的数据是哪些呢。有了上述信息,就可以精准完美的还原出来一次数据增删改操作做的变动了。

2.2.redo log block

我们已经知道了redo log的记录样子,我们可以想一下,redo log就是按照上述格式,一条一条的直接就写入到磁盘上的日志文件里去了吗?

其实MySQL内有另外一个数据结构,叫做redo log block,大概你可以理解为,平时我们的数据不是存放在数据页了的么,用一页一页的数据页来存放数据。那么对于redo log也不是单行单行的写入日志文件的,他是用一个redo log block来存放多个单行日志的。

一个redo log block是512字节,这个redo log block的512字节分为3个部分,一个是12字节的header块头,一个是496字节的body块体,一个是4字节的trailer块尾。在这里面,12字节的header头又分为了4个部分。
在这里插入图片描述
要写入磁盘的redo log,其实应该是先进入到redo log block这个数据结构里去的,然后再进入到磁盘文件里,如下图所示。

redo log数据——》redo log block——》redo log文件
在这里插入图片描述

2.3.redo log buffer

redo log到底是如何通过内存缓冲之后,再进入磁盘文件里去的,这就涉及到了一个新的组件,redo log buffer,他就是MySQL专门设计了用来缓冲redo log写入的。

redo log buffer其实就是MySQL在启动的时候,就跟操作系统申请的一块连续内存空间,然后里面划分出了N多个空的redo log block。mysql的innodb_log_buffer_size可以指定这个redo log buffer的大小,默认的值就是16MB,其实已经够大了,毕竟一个redo log block才512字节而已,每一条redo log其实也就几个字节到几十个字节罢了

redo log都是先写入内存里的redo log block数据结构里去的,写满了一个redo log block,就会继续写下一个redo log block,以此类推,直到所有的redo log block都写满。然后完事儿了才会把redo log block写入到磁盘文件里去的。
在这里插入图片描述
万一要是redo log buffer里所有的redo log block都写满了呢?
那此时必然会强制把redo log block刷入到磁盘中去的!

其实在我们平时执行一个事务的过程中,每个事务会有多个增删改操作,那么就会有多个redo log,这多个redo log就是一组redo log,其实每次一组redo log都是先在别的地方暂存,然后都执行完了,再把一组redo log给写入到redo log buffer的block里去的。

3.redo log buffer 刷盘

redo log block在什么时候会刷入到磁盘文件里去:

  1. 如果写入redo log buffer的日志已经占据了redo log buffer总容量的一半了,也就是超过了8MB 的redo log block在缓冲里了,此时就会把他们刷入到磁盘文件里去;
  2. 一个事务提交的时候,必须把他的那些redo log所在的redo log block都刷入到磁盘文件里去,只有这样,当事务提交之后,他修改的数据绝对不会丢失,因为redo log里有重做日志,随时可以恢复事务做的修改
  3. 后台线程定时刷新,有一个后台线程每隔1秒就会把redo log buffer里的redo log block刷到磁盘文件里去
  4. MySQL关闭的时候,redo log block都会刷入到磁盘里去

当然,绝对保证数据不丢,还得配置一个参数,提交事务把redo log刷入磁盘文件的os cache之后,还
得强行从os cache刷入物理磁盘。

最后给大家说一下redo log日志文件的问题,我们都知道平时不停的执行增删改,那么MySQL会不停的
产生大量的redo log block写入日志文件,那么日志文件就用一个写入全部的redo log?对磁盘占用空间越来越大怎么办?

实际上默认情况下,redo log都会写入一个目录中的文件里,这个目录可以通过show variables like 'datadir’**来查看,可以通过**innodb_log_group_home_dir参数来设置这个目录的。

然后redo log是有多个的,写满了一个就会写下一个redo log,而且可以限制redo log文件的数量,通
innodb_log_file_size可以指定每个redo log文件的大小,默认是48MB,通过innodb_log_files_in_group可以指定日志文件的数量,默认就2个。

所以默认情况下,目录里就两个日志文件,分别为ib_logfile0和ib_logfile1,每个48MB,最多就这2个
日志文件,就是先写第一个,写满了写第二个。那么如果第二个也写满了呢?别担心,继续写第一个,
覆盖第一个日志文件里原来的redo log就可以了。

所以最多这个redo log,mysql就给你保留了最近的96MB的redo log而已,不过这其实已经很多了,毕
竟redo log真的很小,一条通常就几个字节到几十个字节不等,96MB足够你存储上百万条redo log
了!

如果你还想保留更多的redo log,其实调节上述两个参数就可以了,比如每个redo log文件是96MB,
最多保留100个redo log文件

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

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

相关文章

MySQL性能优化(五)undo log是如何实现MVCC的?

之前我们最开始的几篇文章就讲过,你除了写redolog日志还必须要写undo log日志,这个undo log日志是至关重要的,没有他,你根本都没办法回滚事务! 1.事务 1.1.多线程并发执行多个事务 对于我们的业务系统去访问数据库而…

Linux中Shell脚本--awk的用法

语法格式:awk [选项] ‘指令’ 操作文件 常用选项:-F 指定分隔符,分隔符用""引起来 -v:varvalue在awk程序开始之前指定一个值valu给变量var,这些变量值用于awk程序的BEGIN快 -f:后面跟一个保存…

linux下的shell脚本(基础)

Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本,常见的脚本解释器有: bash:是Linux标准默认的shell。bash由Brian Fox和Chet Ramey共同完成,是BourneAgain Shell的缩写,内部命令一共有…

mysql rsync复制,mysql复制又同步

mysql复制再同步由于一个老旧系统没有使用LVM分区,导致mylvmbackup不能使用。为了重新全量同步数据库,发现rsync可以使用,并且锁住数据库的时间不长。1. 首先刷新数据库到文件flush tables with read lock;unlock tables;2. 执行rsync进行数据库同步/usr…

解决springboot中只支持get请求,无法支持post请求

解决springboot中只支持get请求,无法支持post请求 报错信息如下: 405 相关类如下: RestController RequestMapping public class HttpServiceController {Autowiredprivate HttpSecretReport httpSecretReport;Autowiredprivate HttpSecret…

mysql2005卸载步骤,二次安装mysql步骤

1.先将mysql服务停止,并关闭服务页面(否则后面报错:“指定的服务已经标记为删除”):打开“任务管理器”可以找到服务页面2.在控制面板对mysql进行删除。找到并将其卸载,如果没有直接跳过3.在注册表中删除相关目录。(使用组合键&qu…

Spring Boot 默认数据源 HikariDataSource_Spring Boot 中使用 Hikari

Spring Boot 默认数据源 HikariDataSource springboot2.x之后,系统的默认数据源由原来的的org.apache.tomcat.jdbc.pool.DataSource更改为com.zaxxer.hikari.HikariDataSource。 HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3…

matlab取出等高线上的数据,在Python或MATLAB中从等高线图中提取数据

这是一个小型的Matlab脚本,可以完成这项工作(使用一些GUI,在图的斜角处读取guidlines):%// Import the data:imdata importdata(your_picture_file);Gray rgb2gray(imdata.cdata);colorLim [-1 1]; %// this should be set manually%// Ge…

SpringBoot-默认数据源HikariDataSource对数据库操作及自动装配原理

默认数据源HikariDataSource对数据库操作 在创建项目时选择JDBC以及MySQL驱动&#xff0c;让SpringBoot自动装配所需组件 创建完成后默认的pom.xml文件如下 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.o…

matlab fgetl用法,Matlab fgetl strsplit 函数

函数功能&#xff1a;从文件中调用一行数据matlab中fgetl函数&#xff0c;并除去行末的换行符。语法格式&#xff1a;tline fgetl(fid)fid是通过fopen函数打开文件后得到的一个整型的文件标志。fgetl从这个文件中调用一行数据并丢弃其中的换行符。如果抓取成功tline容纳了调用…

HikariCP源码简洁剖析——HikariDataSource_HikariCP的使用和源码

文章目录HikariDataSource的作用源码剖析核心变量构造方法获取链接实例HikariCP的使用和源码简介HikariCP是什么&#xff1f;HikariCP 解决了哪些问题&#xff1f;为什么要使用 HikariCP&#xff1f;本文要讲什么&#xff1f;如何使用 HikariCP需求项目环境引入依赖编写 hikari…

MySQL如何创建沙箱,沙箱环境搭建 - osc_y8w65yuq的个人空间 - OSCHINA - 中文开源技术交流社区...

[toc]测试环境搭建沙箱环境&#xff1a;-------测试环境搭建基础配置&#xff1a;# 1、在沙箱环境下实名认证&#xff1a;https://openhome.alipay.com/platform/appDaily.htm?tabinfo# 2、电脑网站支付API&#xff1a;https://docs.open.alipay.com/270/105898/# 3、完成RSA密…

PHP单选框实现的方法,jQuery简单实现遍历单选框的方法

本文实例讲述了jQuery简单实现遍历单选框的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;1、问题背景&#xff1a;有四个单选框&#xff0c;分别为一年四季&#xff0c;现在需要判断是否选中&#xff0c;如果选中这个单选框&#xff0c;就将其值赋值给输入框2、…

String怎么转成BigDecimal_Java.math.BigDecimal类的使用

1.引言 浮点数值不适用于无法接受舍入误差的金融计算中。 例如&#xff0c;命令System.out.prmtln (2.0-1.1)将打印出0.8999999999999999&#xff0c;而不是人们想象的0.9 。 2.0-1.1的运算结果 这种舍入误差的主要原因是浮点数值采用二进制系统表示&#xff0c;而在二进制系统…

JTS Java空间几何计算、距离、最近点、subLine等计算

文章目录前言地理坐标系和投影坐标系地理坐标系投影坐标系地图投影墨卡托/Web墨卡托常见坐标系地理坐标系和投影坐标系互转EPSG:3857和EPSG:4326Java各坐标系之间的转换&#xff08;高斯、WGS84经纬度、Web墨卡托、瓦片坐标&#xff09;GeotoolsJTSvividsolutions和locationtec…

JTS学习笔记

简介 JTS由加拿大的VividSolutions公司开发&#xff0c;是一个用Java语言描述的几何拓扑套件&#xff0c;遵循OpenGIS的Simple Feature Specification&#xff0c;封装了2D几何类型和非常多的空间分析操作&#xff0c;而且包含了不少常见的计算几何算法实现。 JTS被广泛地应用…

填坑:Maven工程引用GeoTools依赖

这两天在做一个系统的后台&#xff0c;需要用到GeoTools做后端空间分析&#xff0c;记录一下自己遇到的问题。 项目通过Maven进行构建&#xff0c;参照文档Maven Quickstart添加GeoTools依赖和远程仓库地址。 <dependencies><dependency><groupId>org.geotoo…

墨卡托投影介绍

一、墨卡托投影 墨卡托投影&#xff0c;又称正轴等角圆柱投影&#xff0c;由荷兰地图学家墨卡托(G.Mercator)于1569年创拟。假设地球被套在一个圆柱中&#xff0c;赤道与圆柱相切&#xff0c;然后在地球中心放一盏灯&#xff0c;把球面上的图形投影到圆柱体上&#xff0c;再把…

GIS算法:可视化工具JTS TestBuilder

java、python、js都有可以引用的第三方包&#xff0c;实现GIS的空间算法。 java是jts&#xff0c;python是shapely&#xff0c;js是turf。 其中jts值得首先拥有&#xff0c;因为jts提供了一个界面工具JTS TestBuilder&#xff0c;可以在上面绘制图形&#xff0c;验证各种算法…

wkt区域围栏

API文档 http://shengshifeiyang.gitee.io/geotools-learning/ /** * 判断以x,y为坐标的点point(x,y)是否在geometry表示的Polygon中 * param x * param y * param geometry wkt格式 POLYGON((0 0, 10 0, 10 10, 0 10,0 0)) * return */ public static boolean withinGeo(doub…