redo log-Transaction(2)—mysql进阶(六十)

简介: redo log-Transaction(2)—mysql进阶(六十)

前面我们说了为了吧buffer pool的数据持久化到磁盘上,比如修改了一条数据,不可能每次吧整个页的数据都刷新过去,这样耗费性能,innoDB就是把修改的数据记录在redo日志里,redo日志格式主要是spaceId,type,page_number,offset,Data等。Offset记录上一条数据的地址,为了修改上一条记录头部新的next record,data记录的就是真实数据。Redo日志主要关注的就是一条语句修改了多少b+树,针对其中某颗树,可能增加了页,也可能更新了叶子节点或者内节点。他会记录修改日志或者删除日志,而删除日志格式又会分为开始和结束,MLOG_COMP_LIST_START_DELETE和MLOG_COMP_LIST_END_DELETE。

redo log(1)—mysql进阶(五十九)


Mini-transaction


以组的形式写入redo日志

一个sql语句可能修改若干个页面,比如我们前面说的一条insert语句可能修改系统表空间页号为7 页面的max row id属性,还会更新b+树聚簇索引和二级索引对应的页面。由于这些都是发生在buffer pool里,这时候都需要记录在redo日志里,于是在记录的时候,innoDB又把这些分为不同的组。

修改max row_id是不可分割的,向聚簇索引对应的b+树插入一条记录产生的redo日志不可分割,向某个二级索引b+树插入一条记录产生的redo日志不可分割,还有一些其他页面生成的redo日志不可分割。。。

怎么理解不可分割呢,我们向某个索引对应的b+树插入一记录,在插入b+树之前,需要定位向哪个叶子节点代表的数据页,定位到具体的数据页后,有两种可能:

情况一:该数据页的剩余空闲空间充足,足够容纳这一条待插记录,这种就很简单,直接把记录插入这个数据页,记录一条MLOG_COMP_REC_INSERT记录到redo日志,我们吧这种情况称为乐观插入。

情况二:该数据页的剩余空间不足,那么这时候就需要进行所谓的页分裂操作,也就是新建一个叶子节点,插入一条10的记录,那么比10大的记录都会移到新建的叶子节点,吧10插到前面的叶子节点,如果内节点不够用,则同样也需要分裂,这样会记录更多的redo日志,我们称这种为悲观插入。对于这些,我们还需要修改各种段,区的统计信息,各种链表的统计信息,(比如free链表,fsp_free_page链表等等),反正有二三十条记录。

这些操作肯定必须是原子性的,比如不能在系统宕机的时候,redo日志吧聚簇索引的修改记录恢复,而二级索引的修改记录未恢复,这种必定导致数据错误,形成不完成的b+树。如何保证原子性呢,于是innoDB规定这些操作必须以【组】的形式来记录到redo日志,在系统宕机重启时候,要么全部一起恢复,要么一条都不恢复。那么怎么做到呢:

当悲观插入,需要记录多条redo日志。innoDB解决办法是,每次一组日志之后,记录一条特殊的redo日志,MLOG_MULTI_REC_END,type字段对应的十进制数字为31,该类型的结构很简单,只有一个type字段。所以当系统崩溃时候,只有解析到MLOG_MULTI_REC_END才会算是一组完整的操作,如果没有解析到MLOG_MULTI_REC_END,则之前解析的都放弃。

如果有的操作只记录一条数据,然后海特意记录一条MLOG_MULTI_REC_END,不是很浪费吗,这时候如果type字段的第一个比特位是1,代表需要该原子性操作只需要操作一条redo日志。


Redo日志写入过程


Redo log block

innoDB为了更好的进行系统恢复,他们吧通过mtr生成的redo日志都放在大小为512个字节的页中,为了和我们前面表空间的数据页做区别,所以redo日志的页我们称为block(其实他们是差不多的)。Redo log block的结构如下,

log block header:12个字节。

Log block body:496个字节。

Log block trailer:4个字节。

其中redo日志主要存储在body里,我们在看看header 和trailer

Log block header 分为四个属性:

log_block_hdr_no:4个字节,每个block都有一个大于0的唯一标号,本属性就代表唯一值。

log_block_hdr_data_len:表示已经存入redo日志已经使用的字节,从12个字节开始,因为log block body是从12个字节处开始,如果log block body全部填满了,则记录是512字节。

log_block_first_rec_group:多条redo日志会生成一个记录组redo_log_record_group,这个log_block_first_rec_group就代表mtr生成redo日志记录组的偏移量。

log_block_checkpoint_no:表示所谓checkpoint的序号,后面着重介绍。

Log block trailer分为一个属性:

Log_block_checksum:表示block的效验值,用于正确性效验。


Redo日志缓冲区


我们前面说过,为了存储数据到磁盘,会有一个数据的缓冲区buffer pool,同理,redo日志也不能直接写到磁盘,而是需要在mysql启动前,申请一个redo log buffer的连续内存空间(redo日志缓冲区),可以称为log buffer,这篇区域划分为若干个redo log buffer。

可以通过设置启动参数innoDB_log_buffer_size来制定log_buffer的大小,在mysql5.7.21这个版本,默认参数是12mb。


Redo日志写入log buffer


向log buffer 写入redo日志是顺序的,先往前面的block中写,当前面的block满了之后,就往后面空的写,所以如何定位到空的block呢,第一个问题就是block的偏移量,所以innoDB提供了一个buf_free的全局变量来记录block的偏移量,指明redo日志写入的位子。

我们前面说了一个mtr执行过程中可能产生若干条redo日志,这些日志都是不可分割的组,所以并不是每生成一条redo日志,就将其插入log buffer中,而是将mtr产生的日志先存到一个地方,当mtr结束的时候,再将产生的一组数据全部赋值到log_buffer中。

假设我们现在有两个名为T1/T2的事务,每个事务包含两个mtr,我们给mtr命名一下:

事务T1的两个mtr分别为mtr_t1_1和mtr_t1_2。

事务T2的两个mtr分别为mtr_t2_1和mtr_t2_2。

不同的事务可能并发执行,所以T1和T2的mtr可能交替执行,每当一个mtr执行完毕,伴随着该mtr生成的一组redo日志就需要复制到log buffer 中,也就是说不同事务的mtr可能是交替写入log buffer中的。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
存储 缓存 关系型数据库
图解MySQL【日志】——Redo Log
Redo Log(重做日志)是数据库中用于记录数据页修改的物理日志,确保事务的持久性和一致性。其主要作用包括崩溃恢复、提高性能和保证事务一致性。Redo Log 通过先写日志的方式,在内存中缓存修改操作,并在适当时候刷入磁盘,减少随机写入带来的性能损耗。WAL(Write-Ahead Logging)技术的核心思想是先将修改操作记录到日志文件中,再择机写入磁盘,从而实现高效且安全的数据持久化。Redo Log 的持久化过程涉及 Redo Log Buffer 和不同刷盘时机的控制参数(如 `innodb_flush_log_at_trx_commit`),以平衡性能与数据安全性。
1004 5
图解MySQL【日志】——Redo Log
|
存储 SQL 关系型数据库
mysql的undo log、redo log、bin log、buffer pool
MySQL的undo log、redo log、bin log和buffer pool是确保数据库高效、安全和可靠运行的关键组件。理解这些组件的工作原理和作用,对于优化数据库性能和保障数据安全具有重要意义。通过适当的配置和优化,可以显著提升MySQL的运行效率和数据可靠性。
413 16
|
数据库 文件存储 数据安全/隐私保护
YashanDB redo日志文件管理
YashanDB的redo日志文件用于记录数据库物理日志,支持宕机重演和主备复制。 redo日志有4种状态:NEW(新创建)、CURRENT(当前写入)、ACTIVE(未归档或未写盘)和INACTIVE(可复用)。可通过V$LOGFILE视图或直接查看$YASDB_DATA/dbfiles目录来管理redo日志。此外,支持添加、切换和删除redo日志以优化性能或应对磁盘故障等情况,但需注意仅能删除INACTIVE或NEW状态的日志以确保数据安全。
|
存储 SQL 关系型数据库
mysql的undo log、redo log、bin log、buffer pool
MySQL的undo log、redo log、bin log和buffer pool是确保数据库高效、安全和可靠运行的关键组件。理解这些组件的工作原理和作用,对于优化数据库性能和保障数据安全具有重要意义。通过适当的配置和优化,可以显著提升MySQL的运行效率和数据可靠性。
301 4
|
SQL 存储 关系型数据库
简单聊聊MySQL的三大日志(Redo Log、Binlog和Undo Log)各有什么区别
在MySQL数据库管理中,理解Redo Log(重做日志)、Binlog(二进制日志)和Undo Log(回滚日志)至关重要。Redo Log确保数据持久性和崩溃恢复;Binlog用于主从复制和数据恢复,记录逻辑操作;Undo Log支持事务的原子性和隔离性,实现回滚与MVCC。三者协同工作,保障事务ACID特性。文章还详细解析了日志写入流程及可能的异常情况,帮助深入理解数据库日志机制。
2069 0
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
574 3
|
存储 关系型数据库 MySQL
MySQL中的Redo Log、Undo Log和Binlog:深入解析
【10月更文挑战第21天】在数据库管理系统中,日志是保障数据一致性和完整性的关键机制。MySQL作为一种广泛使用的关系型数据库管理系统,提供了多种日志类型来满足不同的需求。本文将详细介绍MySQL中的Redo Log、Undo Log和Binlog,从背景、业务场景、功能、底层实现原理、使用措施等方面进行详细分析,并通过Java代码示例展示如何与这些日志进行交互。
1334 0
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
5171 32
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
监控 安全 Apache
什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球广泛使用的Web服务器软件,支持超过30%的活跃网站。它通过接收和处理HTTP请求,与后端服务器通信,返回响应并记录日志,确保网页请求的快速准确处理。Apache日志分为访问日志和错误日志,对提升用户体验、保障安全及优化性能至关重要。EventLog Analyzer等工具可有效管理和分析这些日志,增强Web服务的安全性和可靠性。
653 9

推荐镜像

更多