热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

数据库日志redologbinlog的解读

1为什么要有redolog?一般当MYSQL更新数据时,有两种情况,追加数据或定位到已经存在的一条数据进行修改。然而磁盘随机读写速度很慢,




1 为什么要有redo log?

一般当MYSQL更新数据时,有两种情况,追加数据或定位到已经存在的一条数据进行修改。然而磁盘随机读写速度很慢,无法满足高IO操作的场景。为了提高写入效率,一般我们可以先将数据写入内存,空闲时再批量刷入磁盘。但是这样就产生了一个问题:内存中的数据不是持久化的,如果掉电,数据就会丢失

为了解决数据丢失的问题,MySQL引入了redo log来解决这个问题。这被称为**WAL(Write-Ahead Logging)**技术,对于非内存数据库,这是一种提高IO效率的常见做法。通过WAL技术,使得在发生崩溃时依靠日志记录,就可以恢复数据,从而确保数据不丢失。


关于WAL(Write-Ahead Logging)

对于非内存数据库,磁盘I/O操作是导致数据库性能低下的主要原因。在数据量相同的情况下,使用WAL日志的数据库系统,可以成倍减少磁盘写入操作,大大提高了数据库磁盘I/O操作的效率,从而提高了数据库性能。


2 redo log的实现

当需要更新记录时,InnoDB引擎先写redo log并更新内存。在适当的时候,例如当磁盘空闲时,将redo log数据刷新到磁盘。在InnoDB引擎中,redo log的大小是固定的,例如,它可以配置为一组四个文件,每个文件大小为1GB,因此总共可以记录4GB的操作。
在这里插入图片描述
write pos用于记录当前位置,在写入时移动,注意是循环移动的。checkpoint用于标记要擦除的位置,在擦除时往后移动,注意也是循环移动的。记录在被擦除之前会更新到磁盘数据文件。
在这里插入图片描述
write pos到check point之间的部分是redo log空着的部分,用于记录新的记录;check point到write pos之间是redo log待落盘的数据页更改记录。

如果write pos完成最后一个文件的写入,它将移动到ib-log-file-0并再次开始写入。

如果write pos赶上check point,则表示redo log已满,因此无法执行新的更新,必须停止并擦除一些数据,将数据同步到磁盘,然后再继续以上步骤。


3 如何查看redo log 配置参数

每个InnoDB存储引擎至少有一个重做日志文件组,每个文件组至少有两个重做日志文件,默认为ib-log-file-0和ib-log-file-1。
可使用以下命令查看参数配置信息:

show variables like '%innodb_log%';

4 关于Binlog

redo log是InnoDB引擎特有的,可以记录数据,并保证数据的安全性,那么其它存储引擎如何记录数据呢?在Server级别,MySQL有自己的日志,即Binlog(归档日志)。了解MySQL逻辑架构的同学应该知道,Mysql不是一个整体,MySQL = Server层 + 不同的数据存储引擎

Binlog用于记录MySQL数据库表结构和表数据的所有变更操作,但不包括select和show查询操作。Binlog以事件的形式记录下来,包括语句消耗的时间。Binlog日志最重要的两个使用场景如下:
主从复制:在主库开启Binlog功能,使主库可以将Binlog传递给从库,从库获取Binlog并实现数据恢复,实现主从数据一致性。
数据恢复:通过mysqlbinlog工具恢复数据。

binlog日志有三种格式,分别为STATMENT、ROW和MIXED。在 MySQL 5.7.7之前,默认的格式是STATEMENT,MySQL 5.7.7之后,默认值是ROW。日志格式通过binlog-format指定。

STATMENT:
Statement模式记录的是所有数据库操作对应的SQL语句,如INSERT、UPDATE 、DELETE 等DML语句,CREATE 、DROP 、ALTER 等DDL,所以,从理论上讲,只要按顺序执行这些SQL 语句,就可以实现不同数据库间的数据复制。

优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO, 从而提高了性能;
缺点:在某些情况下会导致主从数据不一致,比如执行sysdate()、sleep()等。

ROW:
Row模式更关心每一行的变更,这种在实际应用中会更普遍一点,因为有时候更关心数据的变化情况,例如一个订单被创建出来,司机通过App接收了某个运输任务等。

优点:不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题;
缺点:会产生大量的日志,尤其是alter table的时候会让日志暴涨

MIXED:
Statement模式和Row模式的混合体,因为Statement模式和Row模式都有各自的不足,前者可能会导致数据不一致,而后者则会占用大量的存储空间。一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog


5 为什么有两个日志?

MySQL一开始没有InnoDB引擎,MySQL自带的引擎是MyISAM,但是MyISAM没有处理崩溃恢复数据的能力,binlog日志只是用来归档。InnoDB后来作为插件添加,它实现了自己的日志系统来保护数据,防止崩溃丢失数据问题。


6 bin log和redo log的区别

内容不同:redo log是物理日志,记录的是“在某个数据页上做了什么修改”;binlog是记录的这个语句的原始逻辑,比如“给D=2这一行的C字段加1”。

不同级别:redo log只能和InnoDB引擎一起使用,而binlog位于MySQL服务器级别,可用于所有引擎。

磁盘存储形式不同:redo log是循环写的,空间固定会用完;binlog是可以追加写入的。“追加写“是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

写入的时间不同:binlog通常在一个事务提交时写入,而redo log会在不同的时间点写入。(注意:未提交的事务redo log也可能被刷新到磁盘)

对于InnoDB存储引擎而言,只有在事务提交时才会记录biglog,此时记录还在内存中,那么biglog是什么时候刷到磁盘中的呢?mysql通过sync_binlog参数控制biglog的刷盘时机,取值范围是0-N:
0:不去强制要求,由系统自行判断何时写入磁盘;
1:每次commit的时候都要将binlog写入磁盘;
N:每N个事务,才会将binlog写入磁盘。
从上面可以看出,sync_binlog最安全的是设置是1,这也是MySQL 5.7.7之后版本的默认值。但是设置一个大一些的值可以提升数据库性能,因此实际情况下也可以将值适当调大,牺牲一定的一致性来获取更好的性能。

作用不同:binlog日志只用于归档,只依靠binlog是没有crash-safe能力的。但只有redo log也不行,因为redo log是InnoDB特有的,且日志上的记录落盘后会被覆盖掉。因此需要binlog和redo log二者同时记录,才能保证当数据库发生宕机重启时,数据不会丢失。


7 两阶段提交

由于redo-log是在InnoDB层,而bin-log是在 Server 层,这样就引入了一个新的问题。如果redo log写入成功,但是在bin-log写入磁盘之前,程序crash了,说明事务还没有提交,所以redo-log里写入的新数据是无效的。重新启动数据库进行数据恢复会将redo-log数据恢复到磁盘,从而创建无效数据。

为了解决这个问题,引入了两阶段提交。

在第一阶段,redo-log写入并处于准备状态。Server层将bin-log数据保存到磁盘,然后执行器调用引擎的提交事务接口提交事务,把redo-log变更为已提交状态,更新完成。通过两阶段提交协议保证了redo-log数据和bin-log数据的一致性。


8 一条更新语句的执行过程

假设我们现在要执行SQL:

update table_test set a = a+1 where id = 2;

首先,客户端通过连接器连接并确定权限。

验证后,SQL会经过解析器进行词法和语法分析(AST),如果是Update语句,MySQL将清除查询表的所有查询缓存table_test。(一般不建议开启查询缓存,通常会影响性能)。

优化器优化经过验证的SQL,匹配id索引,并生成执行计划。

执行器获取最终的SQL,并调用相应存储引擎的接口开始执行该更新SQL。

InnoDB引擎打开一个事务,执行引擎首先从内存中查询是否有数据id=2,如果匹配则设置对应的数据为field+1,然后将其保存到内存中。如果内存中没有查询到id=2的数据,那么它将以页的形式加载磁盘中的数据到内存,然后更新并保存到内存中。

然后InnoDB引擎会将数据行保存到redo-log,此时处于准备状态,表示已经准备好可以提交事务了。

执行器将生成相应的bin-log并将其写入磁盘。

事务被提交,然后redo-log也被提交。

这样事务就执行完成了!!!!







推荐阅读
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了adg架构设置在企业数据治理中的应用。随着信息技术的发展,企业IT系统的快速发展使得数据成为企业业务增长的新动力,但同时也带来了数据冗余、数据难发现、效率低下、资源消耗等问题。本文讨论了企业面临的几类尖锐问题,并提出了解决方案,包括确保库表结构与系统测试版本一致、避免数据冗余、快速定位问题等。此外,本文还探讨了adg架构在大版本升级、上云服务和微服务治理方面的应用。通过本文的介绍,读者可以了解到adg架构设置的重要性及其在企业数据治理中的应用。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • Java学习笔记之使用反射+泛型构建通用DAO
    本文介绍了使用反射和泛型构建通用DAO的方法,通过减少代码冗余度来提高开发效率。通过示例说明了如何使用反射和泛型来实现对不同表的相同操作,从而避免重复编写相似的代码。该方法可以在Java学习中起到较大的帮助作用。 ... [详细]
  • 集成电路企业在进行跨隔离网数据交换时面临着安全性问题,传统的数据交换方式存在安全性堪忧、效率低下等问题。本文以《Ftrans跨网文件安全交换系统》为例,介绍了如何通过丰富的审批流程来满足企业的合规要求,保障数据交换的安全性。 ... [详细]
  • 本文介绍了sqlserver云存储和本地存储的区别,云存储是将数据存储在网络上,方便查看和调用;本地存储是将数据存储在电脑磁盘上,只能在存储的电脑上查看。同时提供了几种启动sqlserver的方法。此外,还介绍了如何导出数据库的步骤和工具。 ... [详细]
  • 本文主要复习了数据库的一些知识点,包括环境变量设置、表之间的引用关系等。同时介绍了一些常用的数据库命令及其使用方法,如创建数据库、查看已存在的数据库、切换数据库、创建表等操作。通过本文的学习,可以加深对数据库的理解和应用能力。 ... [详细]
author-avatar
milkchocolate1981
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有