MySQL中的Redo-log是什么?有什么作用?

用来实现数据的恢复,数据被更新到缓冲区但没刷磁盘,然后MySQL宕机了,MySQL会通过日志恢复数据。

1.为什么需要Redo-log日志?

MySQL绝大部分引擎都是基于磁盘存储数据的,每次读写数据都走磁盘,效率十分低下,InnoDB引擎在设计时,当MySQL启动后就会在内存中创建一个BufferPool,运行过程中会将大量操作汇集在内存中进行,比如写入数据时,先写到内存中,然后由后台线程再刷写到磁盘。

使用BufferPool提升了MySQL整体的读写性能,但它是基于内存的,意味着随着机器的宕机、重启,其中保存的数据会消失,那当一个事务向内存中写入数据后,突然宕机了未刷写到磁盘的数据就会丢失,这违背了事务ACID原则中的持久性,所以Redo-log的出现就是为了解决该问题,

Redo-log是一种预写式日志,即在向内存写入数据前,会先写日志,当后续数据未被刷写到磁盘、MySQL崩溃时,就可以通过日志来恢复数据,确保所有提交的事务都会被持久化。

2. Redo-log的刷盘策略

刷盘的时机由 innodb_flush_log_at_trx_commit 参数来控制,默认是处于第二个级别,也就是每次提交事务时都会刷盘,这也就意味着一个事务执行成功后,相应的Redo-log日志绝对会被刷写到磁盘中,因此无需担心会出现丢失风险。

3. Redo-log 为什么多此一举

先刷写一次Redo-log日志到磁盘,后台线程再根据Redo-log日志把数据落盘,这样做好处很大:

  • 日志比数据先落入磁盘,就算MySQL崩溃也可以通过日志恢复数据。
  • 写日志时是以追加形式写到末尾,而写数据时则是计算数据位置,随机插入。

写日志的时候,只需要将记录追加到日志文件的尾部即可,这是按顺序写入,但写入表数据时,还需要先先计算数据的位置,比如修改一条数据时,需要先判断这条数据在磁盘文件中的那个位置,找到了位置再写入,这是随机写入,顺序写入的速度会比随机写入快很多很多。

所以写日志会比写数据落盘快,因此日志落盘后返回,比数据落盘后返回要快,对于客户端而言,响应时间会更短。

4. Redo-log相关的参数

Redo-log日志中,较为重要的系统参数:

  • innodb_flush_log_at_trx_commit:设置redo_log_buffer的刷盘策略,默认每次提交事务都刷盘。
  • innodb_log_group_home_dir:指定redo-log日志文件的保存路径,默认为./。
  • innodb_log_buffer_size:指定redo_log_buffer缓冲区的大小,默认为16MB。
  • innodb_log_files_in_group:指定redo日志的磁盘文件个数,默认为2个。
  • innodb_log_file_size:指定redo日志的每个磁盘文件的大小限制,默认为48MB。

Redo-log的本地磁盘文件个数是两个,MySQL通过来回写这两个文件的形式记录Redo-log日志,用两个日志文件组成一个"环形",如下:

  • write pos:这根指针用来表示当前Redo-log文件写到了哪个位置。
  • check point:这根指针表示目前哪些Redo-log记录已经失效且可以被擦除(覆盖)。

当一个事务写了redo-log日志、并将数据写入缓冲区后,但数据还未写到本地的表数据文件中,此时这个事务对应的redo-log记录就为上图中的蓝色,而当一个事务所写的数据也落盘后,对应的redo-log记录就会变为红色。

当write pos指针追上check point指针时,红色区域就会消失,也就代表Redo-log文件满了,再当MySQL执行写操作时就会被阻塞,因为无法再写入redo-log日志了,所以会触发checkpoint刷盘机制,将redo-log记录对应的事务数据,全部刷写到磁盘中的表数据文件后,阻塞的写事务才能继续执行。

关于checkpoint机制的系统参数:

  • innodb_log_write_ahead_size:设置checkpoint刷盘机制每次落盘动作的大小,默认为8K,如果要设置,必须要为4k的整数倍,这跟read-on-write问题有关。
  • innodb_log_compressed_pages:是否对Redo日志开启页压缩机制,默认ON,这跟InnoDB的页压缩技术有关。
  • innodb_log_checksums:Redo日志完整性效验机制,默认开启,必须要开启,否则有可能刷写数据时,只刷一半,出现类似于"网络粘包"的问题。
相关推荐
愛~杦辷个訾6 分钟前
芋道项目,商城模块数据表结构
java·sql·芋道·yudao-cloud·芋道商城
Smile丶凉轩2 小时前
Qt 界面优化(绘图)
开发语言·数据库·c++·qt
昔柯的修炼日记3 小时前
使用 Navicat 将 Excel 导入数据库
数据库
进击的雷神5 小时前
数据库知识全面考查:从基础概念到实战应用
jvm·数据库·oracle
Le_ee6 小时前
sqli-labs靶场第七关——文件导出注入
数据库·sql·网络安全·php·sql注入·sqli—labs
dddaidai1236 小时前
分布式ID和分布式锁
redis·分布式·mysql·zookeeper·etcd
不知几秋6 小时前
Maven
java·数据库·maven
政沅同学6 小时前
数据库实验报告 SQL SERVER 2008的基本操作 1
数据库
lyw2056196 小时前
MySQL八股(自用)
数据库·mysql
MMMMMMMMMMemory7 小时前
pgsql14自动创建表分区
数据库·pgsql