标签:申请 模式 保存 文件系统 构建 拷贝 数据 for 安全
磁盘(ib_logfile0~N)重做日志
内存(innodb_log_buffer)日志缓冲区
预先分配至少2个日志文件,第一个文件开头和最后一个文件结尾进行首尾相连以循环的方式重复使用。
用于在必要时(如:崩溃恢复时)可以使用Redo Log中的数据来重新应用到InnoDB数据文件中,使得InnoDB能够恢复到一致性状态。
日志先行(WAL:Write Ahead Log),Redo Log 优先于数据页写到磁盘。
对数据表做修改时,每个数据记录的修改都会写入Redo Log Buffer中(记录重做日志)。当一个页面的修改操作完成时,首先Redo Log Buffer将执行flush同步到Redo Log文件,之后才可能将实际更改数据写入磁盘(buffer pool中的脏页刷新到数据文件)。
批量刷写,如果系统参数innodb_flush_log_at_trx_commit设置为1,则每个事务提交时也会将Redo Log Buffer同步到磁盘文件中。
Redo Log 日志组结构
用于撤消(或还原)对InnoDB中存储的数据的变更及回滚事务,也用于实现多版本控制(mvcc),通过构建一致性视图(read view)实现对数据库的一致性读。
对数据库的每一次更改,Undo Log都会保存之前版本的数据和回滚指针(每个聚簇(PK)索引记录都有的一个指向该修改记录之前版本数据的指针),另外,每个Undo Log的变更也必须记录到Redo Log中。
Undo Log在共享表空间的基本结构
Log Sequence Number(LSN)
一个64位无符号整数,表示Redo Log系统中的时间点,也是事务写入Redo Log的字节总量,从日志初始化(数据库初始化安装)时间点开始单调递增计数
LSN存放在Redo Log和每个数据页,数据库每次启动,都会比较磁盘数据页和 Redo Log 的LSN,必须两者一致数据库才能正常启动,如果不一致就会触发CR(崩溃恢复),最终保证一致
在数据恢复时,通过LSN做比较运算,可以判断出每个数据页是否需要进行恢复操作
可以在存储引擎状态信息中获取
show engine innodb status\G
使用LSN常见对象
Checkpoint 指将脏页刷写到磁盘的动作
脏页(Dirty Page):发生了修改,没写入到磁盘之前的内存页称之为脏页.
Checkpoint LSN 是一个由LSN值表示的整型值,一个时间点,在Checkpoint LSN之前的每个数据页(buffer pool中的脏页)的更改都已经落盘(刷新到数据文件中),Checkpoint 完成后,在Checkpoint LSN之前的Redo Log就不再需要了
Checkpoint 用于解决:全量Redo Log恢复时间太长、buffer pool中的空闲页不够用时将脏页刷新到磁盘数据文件、Redo Log空间不够用时将脏页刷新到磁盘数据文件等问题
Checkpoint 方式有两种:Sharp Checkpoint和Fuzzy Checkpoint(又可根据不同的场景细分)
7
个字节,6
个字节,最大事务号写入系统表空间的TRX_SYS页,伴随着整个事务生命周期.Undo Log
日志空间Undo Log
中Undo Log
的修改记录写入Redo Log
中buffer pool
中修改数据页,回滚段指针指向Undo Log
中该记录之前的版本Undo Log
中buffer pool
中该记录修改之后的数据页被标记为"脏页"(需要刷新到磁盘的数据页)此时其他事务:
- 一旦记录被修改,即使没有提交,其他事务也可能会看到被修改后的记录,这依赖于他们的事务隔离级别而定
- 如果是RU隔离级别,则使用索引页读取最新版本记录
- 如果是RU隔离级别,则查找记录的最新提交版本
- 如果是RR隔离级别,则查找与其read view相对应的记录版本
- 任何需要使用索引页来读取比最新的版本记录旧的版本记录时,都必须使用Undo Log来重建之前的版本记录
触发方式:
定期执行Checkpoint
确保比Checkpoint 点更旧(比Checkpoint LSN小)的脏页已刷新到表空间文件,如果存在有比Checkpoint LSN大的脏页,则立即刷新脏页到数据文件中。说白了Checkpoint机制主要作用就是用于刷新脏页
把Checkpoint LSN写到Redo Log Header中 (从这个Checkpoint LSN开始,之前的Redo Log记录不再需要)
后台线程Purge
后台线程连续不断地根据需要定期执行Purge,包括Undo Log和历史链表
查找每个回滚段中不再需要的最旧的Undo Log
执行流程:
PS:对于后台线程刷脏部分,执行刷新脏页时,与该脏页的事务是否提交无关,只需要确保该页对应LSN号的Redo Log记录落盘,而不会去判断事务的状态是否是提交还是未提交状态,因为,数据页结构中并没有地方单独记录事务的状态(即,无法判断事务是否提交),只是在每行数据中有记录事务号、回滚段指针(所以一个页中也可能包含多个事务的修改记录)。当需要对某个事务进行回滚时,重新从表空间中读取这个未提交的脏页,使用undo log中的反向数据进行反向修改,然后再重新刷脏。
原理:使用所有独立表空间的表名和表空间ID创建一个名称到ID的映射
PS:
Checkpoint
往后扫描到的Redo Log
记录将被应用到各个数据文件中Undo Log
中恢复处于‘ACTIVE
‘状态的事务,重新生成Read View
Undo Log
回滚未提交的‘ACTIVE
‘状态的事务PREPARE
状态的事务,如果打开了binlog
且在binlog
有找到对应事务的日志则重新提交,否则回滚原子性 A
ACID模型 的原子性方面主要涉及InnoDB
事务。相关的MySQL功能包括:
一致性 C
ACID模型 的一致性方面主要涉及内部InnoDB
处理,以防止数据崩溃。相关的MySQL功能包括:
InnoDB
doublewrite buffer :默认存储在ibdataN中,数据页写入过程中,建立的副本。InnoDB
崩溃恢复 :数据库意外宕机时,通过redo前滚和undo回滚,保证数据的最终一致。隔离性 I
ACID模型 的隔离性方面主要涉及InnoDB事务
,尤其是适用于每个事务的隔离级别。相关的MySQL功能包括:
SET ISOLATION LEVEL
隔离级别设置声明。InnoDB
锁 。可以通过INFORMATION_SCHEMA
表查看详细信息 。持久性 D
ACID模型 的持久性方面涉及与特定硬件配置交互的MySQL软件功能。相关的MySQL功能包括:
InnoDB doublewrite buffer
,由innodb_doublewrite
配置选项打开和关闭 。innodb_flush_log_at_trx_commit
。sync_binlog
。innodb_file_per_table
。fsync()
系统调用的支持。InnoDB核心特性:自动故障恢复。先前滚再回滚,先应用redo再应用undo。
Redo Log 应用在事务ACID过程中,实现的是“D”持久化的作用,对于AC也有相应的作用。
Undo Log 应用在事务ACID过程中,实现的是“A” 原子性的作用,对于CI也有相应的作用。
用户发起事务语句(begin;DML;commit;
)
begin;
,立即分配一个TXID=tx_01
。
DML;
,将需要修改的磁盘数据页(PageNo=10,数据,LSN=3515),加载到内存(buffer_pool
)缓冲区。
申请 undo log 日志空间,保存数据到回滚日志(逆向操作的逻辑日志)
记录 undo log 操作到redo log
。
DBWR线程,在内存中,修改数据页头部(记录TRX_ID+ROLL_PTR),更新数据页(PageNo=10,变化的数据,LSN=3515+变化的字节)形成脏页。
LOGBWR日志写线程,将 数据页的变化 + LSN=3515+变化的字节 + TXID 存储到 redo buffer
。
如果此时系统宕机,内存数据会全部丢失:
buffer_pool
和磁盘数据页的LSN是否一致。log buffer
LSN = 数据页 LSN :不需要进行前滚和回滚。undolog直接被标记为可覆盖状态。MySQL正常启动。commit;
,LOGBWR线程,将redo buffer
写入磁盘中的redolog
日志文件(ib_logfileN)。
基于批量刷写redo机制:在事务commit时,会顺便将redo buffer
中其他未提交的redolog
也一并刷到磁盘。日志记录时,使用COMMIT标记区分状态。
基于WAL(日志先行)机制:在日志完全写入磁盘后,给此日志打上commit标记,commit命令才算执行成功。
此时 binlog 完全写入磁盘,但脏页没有写入磁盘,由其他后台线程检测刷脏(CheckPoint
)
如果此时系统宕机,内存数据会全部丢失:
buffer_pool
和磁盘数据页的LSN是否一致。log buffer
LSN > 数据页 LSN :加载ib_logfileN到log buffer
,磁盘数据页到buffer_pool
。使用redolog
重构脏页(前滚)。
rollback;
),根据DB_TRX_ID + DB_ROLL_PTR,找到undolog,实现回滚。redolog
LSN 一至。MySQL正常启动。innodb_flush_log_at_trx_commit 作用:控制innodb将log buffer中的数据,写入日志文件并flush磁盘的时间点。
select @@innodb_flush_log_at_trx_commit;
参数说明
0:每秒写入一次日志并将其刷新到磁盘。未刷新日志的事务可能会在崩溃中丢失。
1:每次事务提交时,日志都会写入并刷新到磁盘。完全符合ACID,默认设置。
2:在每次事务提交后写入日志,并每秒刷新一次到磁盘。未刷新日志的事务可能会在崩溃中丢失。
Innodb_flush_method 作用:控制的是,log buffer 和data buffer,刷写磁盘的时候是否经过文件系统缓存。
select @@innodb_flush_method;
参数说明
fsync或0: 刷新日志和数据缓冲区到磁盘,都走OS buffer
O_DSYNC或1: 刷新日志缓冲区到磁盘,不走OS buffer
O_DIRECT或4: 刷新数据缓冲区到磁盘,不走OS buffer
官方参数说明
fsync或0: InnoDB使用fsync()数据和日志文件。默认设置。
O_DSYNC或1: InnoDB使用O_SYNC打开和刷新日志文件,使用fsync()刷新数据文件。
O_DIRECT或4: InnoDB使用O_DIRECT打开数据文件,使用fsync()刷新数据和日志文件。
O_DIRECT_NO_FSYNC: InnoDB在刷新I/O期间使用O_DIRECT,但在每次写操作后跳过fsync()。
使用建议
# 最高安全模式
innodb_flush_log_at_trx_commit=1
Innodb_flush_method=O_DIRECT
# 最高性能模式
innodb_flush_log_at_trx_commit=0
Innodb_flush_method=fsync
MySQL之7---InnoDB 和 事务流程、Crash Recovery、ACID
标签:申请 模式 保存 文件系统 构建 拷贝 数据 for 安全
原文地址:https://www.cnblogs.com/backups/p/mysql_7.html