简介
重做日志(Redo Log)
介绍
相关参数
0:由master 线程周期性任务刷新(下面具体介绍)。
1:在事务 commit 时,fsync写入磁盘文件。
2:在事务 commit 时,将 redo log buffer写入到文件系统缓存(file system buffer),由系统内部来fsync到磁盘文件。如果数据库实例crash,不会丢失redo log,但是如果服务器crash,由于文件系统缓存还来不及fsync到磁盘文件,所以会丢失这一部分的数据。
存在形式
log_block_hdr_no:(4字节)该日志块在redo log buffer中的位置ID。
log_block_hdr_data_len:(2字节)该log block中已记录的log大小。写满该log block时为0x200,表示512字节。
log_block_first_rec_group:(2字节)该log block中第一个log的开始偏移位置。
lock_block_checkpoint_no:(4字节)写入检查点信息的位置。
redo_log_type:占用1个字节,表示redo log的日志类型。
space:表示表空间的ID,采用压缩的方式后,占用的空间可能小于4字节。
page_no:表示页的偏移量,同样是压缩过的。
redo_log_body:表示每个重做日志的数据部分,恢复时会调用相应的函数进行解析。
持久化方式
MySQL master 线程周期性任务:每秒一次,将 redo log buffer 刷新到磁盘(即使这个事务尚未提交)
MySQL master 线程周期性任务:每10秒一次;
redo log buffer size:缓冲区剩余空间(innodb_log_buffer_size参数)小于1/2时;
redo log file:磁盘中的redo log文件大小已经达到设置的阈值(innodb_log_files_in_group * innodb_log_file_size 参数),触发 async/sync flush checkpoint,及时将一些脏页刷新到磁盘数据页,并同时将redo log buffer刷新到redo log,然后更新redo log file 相应的 log sequence number值;
sharp checkpoint:在重用redo log文件(例如切换日志文件)的时候,将所有已记录到redo log中对应的脏数据刷到磁盘;
fuzzy checkpoint:一次只刷一小部分的日志到磁盘,而非将所有脏日志刷盘。有以下几种情况会触发该检查点:
master thread checkpoint:由master线程控制,每秒或每10秒刷入一定比例的脏页到磁盘。
flush_lru_list checkpoint:从MySQL5.6开始可通过 innodb_page_cleaners 变量指定专门负责脏页刷盘的page cleaner线程的个数,该线程的目的是为了保证LRU列表有可用的空闲页。
async/sync flush checkpoint:同步刷盘还是异步刷盘。例如还有非常多的脏页没刷到磁盘(非常多是多少,有比例控制),这时会选择同步刷到磁盘,但这很少出现;如果脏页不是很多,可以选择异步刷到磁盘,如果脏页很少,可以暂时不刷脏页到磁盘
dirty page too much checkpoint:脏页太多时强制触发检查点,目的是为了保证缓存有足够的空闲空间。too much的比例由变量innodb_max_dirty_pages_pct 控制,MySQL 5.6默认的值为75,即当脏页占缓冲池的75%后,就强制刷一部分脏页到磁盘。由于刷脏页需要一定的时间来完成,所以记录检查点的位置是在每次刷盘结束之后才在redo log中标记的。
设置为0:会做清除脏页和插入缓冲区的合并操作,也会将脏页全部刷新到磁盘上面去,但是这个时候关闭的速度也是最慢的,但是restart的时候也是最快的;
设置为1:关闭MySQL的时候不会做清除脏页和插入缓冲区的合并操作,只会将脏页刷新到磁盘;
设置为2:不会做清除脏页和插入缓冲区的合并操作,也不会将脏页刷新到磁盘,但是会刷新到redo log里面,再下次启动mysql的时候恢复;
回滚日志(Undo Log)
介绍
更新删除
delete:不会直接删除,而是将delete对象标记delete flag为删除,最终由purge线程完成删除操作。
update:
更新键为主键:先删除新纪录,再插入原纪录;
更新键为非主键:在undo log中反向记录update命令;
id=1的数据第一次插入,因为insert时,原始的数据并不存在,所以回滚时把insert undo log丢弃即可;
更新数据时,用排他锁锁定该行;
记录redo log;
把该行修改前的值Copy到undo log,即纪录原纪录{1,'A'}的逻辑日志;
修改当前行的值,填写事务编号,使该行纪录的回滚指针指向undo log中的修改前的行({1,'A'}的undo日志行);
更新数据为{1,‘C’}时与更新{1,‘B’}相同,更新完成后此时undo log中有有两行记录({1,'B'}-->{1,'A'}),并且通过回滚指针连在一起。因此,如果undo log一直不清除,则会通过当前记录的回滚指针回溯到该行创建时的初始内容,所幸的时在Innodb中存在purge线程,它会查询那些比现在最老的活动事务还早的undo log,并删除它们,从而保证undo log文件不至于无限增长。
相关参数
存在形式
slot 0 ,预留给系统表空间;
slot 1~32,预留给临时表空间,每次数据库重启的时候,都会重建临时表空间;
slot 33~127,如果有独立表空间,则预留给UNDO独立表空间;如果没有,则预留给系统表空间;
二进制日志(Binlog)
介绍
| 模式 | 定义 | 优点 | 缺点 |
|---|---|---|---|
| statement | 记录修改的SQL语句 | 日志文件小,节约IO,提高性能 | 准确性差,会出现主从不一致的情况 |
| row | 记录每行实际数据的变更 | 准确性强,能清楚的记录每一行数据修改的细节 | 日志文件大,较大的IO |
| mixed | 上面两种模式的混合 | 准确性强,日志文件大小适中 | 会出现主从不一致的情况 |
配置binlog
[mysqld]#binlog日志名称前缀log-bin=mysql-bin#默认值未0,如果使用默认值则不能和从节点通信,这个值的区间是:1到(2^32)-1server-id=1#复制模式binlog_format = ROW############################################################binlog路径log_bin = var/lib/mysql/mysql-bin.log#日志过期时间,设置为0则永不过期expire_logs_days = 7#超过max_binlog_size或超过6小时会切换到下一序号文件max_binlog_size = 100M#日志缓冲大小,通过show status like 'binlog_%';查看调整写入磁盘的次数,写入磁盘为0最好binlog_cache_size = 16Mmax_binlog_cache_size = 256M#当slave从库宕机后,假如relay-log损坏了,#导致一部分中继日志没有处理,则自动放弃所有未执行的relay-log,#并且重新从master上获取日志,这样就保证了relay-log的完整性。relay_log_recovery = 1#二进制日志(binary log)同步到磁盘的频率sync_binlog = 1#每次事务提交将日志缓冲区写入log file,并同时flush到磁盘。innodb_flush_log_at_trx_commit = 1
查看binlog日志
mysql> show binlog events; #只查看第一个binlog文件的内容mysql> show binlog events in 'mysql-bin.000001';#查看指定binlog文件的内容mysql> show binary logs; #获取binlog文件列表mysql> show master status;#查看当前正在写入的binlog文件
#基于开始/结束时间#--start-datetime 指定开始时间#--stop-datetime 指定截止时间#-d 选项,指定数据库名称mysqlbinlog --start-datetime='2020-08-01 00:00:00' --stop-datetime='2020-08-17 12:00:00' -d wyk /var/lib/mysql/mysql-bin.000001#-o 选项,o代表偏移offset,指定偏移量mysqlbinlog -o 10 mysqld-bin.000001#-j 从一个特定位置提取mysqlbinlog -j 9527 mysqld-bin.000001 > from_id_9527.sql#--stop-position 截止到一个特定位置的条目mysqlbinlog --stop-position=9527 mysqld-bin.000001 > upto_id_9527.sql#使用Linux重定向命令,将可读的输出文本存储到一个文件中mysqlbinlog mysqld-bin.000001 > output.log#也可以使用 -r选项将输出存储到一个文件中mysqlbinlog -r output.sql mysqld-bin.000001
两阶段提交
总结
| redo | undo | binlog | |
| 作用 | 保持事务的持久性 | 帮助事务回滚及MVCC的功能 | 进行Point-In-Time的恢复及主从复制环境的建立 |
| 产生主体 | InnoDB | InnoDB | MySQL |
| 类型 | 物理日志 | 逻辑日志 | 逻辑日志 |
| 内容 | 每个页的修改 | 修改前的行数据 | 执行的SQL语句 |
| 每个事务的日志数量 | 修改的行数据量 | 修改的行数据量 | 事务提交后记一条SQL语句 |
| 写入方式 | 循环写 | 循环写 | 追加写 |
希望本文对你有帮助,请点个赞鼓励一下作者吧~ 谢谢!








