MySQL日志模块

学习链接

https://www.bilibili.com/video/BV1xh411Z79d?p=38

https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html

日志模块简介

Bin log:逻辑日志(记录逻辑运算过程),相当于AOF,也相当于git的log记录所有操作
Redo log:物理日志(记录最终逻辑运算结果),相当于RDB

二进制日志是在存储引擎的上层产生的,不管是什么存储引擎,对数据库进行了修改都会产生二进制日志。而redo log是innodb层产生的,只记录该存储引擎中表的修改。并且二进制日志先于redo log被记录。
RedoLog事务日志记录的是物理页的情况,它具有幂等性,因此记录日志的方式极其简练。幂等性的意思是多次操作前后状态是一样的,例如新插入一行后又删除该行,前后状态没有变化。而二进制日志记录的是所有影响数据的操作,记录的内容较多。例如插入一行记录一次,删除该行又记录一次。
redolog也有重写机制将最新结果写入到log中,注意与AOF的重写不一样,AOF是合并操作,redolog是重写数据

Bin log

在这里插入图片描述

二进制日志:MYSQL提供了工具去解析二进制日志,解析出标志位等
物理日志会有大小限制,而bin log则没有大小限制
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Flush logs操作后,之后的操作生成到新的bin log日志文件中

Bin log写入:
事务执行过程中先把日志写到binlog cache中,等事务提交的时候再把cache写到binlog文件fsync落盘并清空cache,这一点和redolog/AOF很像。一个事务的 binlog不能被拆开,不论事务多大也要确保一次性写入binlog。每个线程都会申请一块binlog cache,内存空间大小由参数 binlog_cache_size控制。如果超过参数设置的大小就要暂存到磁盘。而write和fsync 的时机由参数sync_binlog决定(双1参数之1)

查看bin log日志
在这里插入图片描述

End_log_pos标志位,标志操作在数据库的起始位置 在这里插入图片描述

timestamp:时间点记录

恢复可以恢复按照时间段进行恢复,也可以按照pos位置进行恢复,恢复数据库中某一段位置区间内所有的数据
在这里插入图片描述
记录了数据库与表名

恢复数据的操作: 在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Redo Log

背后是WAL机制:ignite持久化机制,先写日志再写磁盘
在这里插入图片描述

先写日志,再写磁盘

检查机制:检测到MySQL在空闲时将redo log file中的数据写入到磁盘文件中,防止数据库雪崩

内存中(buffer pool)未刷到磁盘的数据称为脏数据(dirty data)。由于数据和日志都以页的形式存在,所以脏页表示脏数据和脏日志。

不仅仅是日志需要刷盘,脏数据页也一样需要刷盘。

https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html
在innodb中,数据刷盘的规则只有一个:checkpoint。
checkpoint触发后,会将buffer中脏数据页和脏日志页都刷到磁盘。

innodb存储引擎中checkpoint刷入机制上来说分为如下两种:
sharp checkpoint:在重用redo log文件(例如切换日志文件)的时候,将所有已记录到redo log中对应的脏数据刷到磁盘。
fuzzy checkpoint:一次只刷一小部分的日志到磁盘,而非将所有脏日志刷盘。有以下几种情况会触发该检查点:

  1. master thread checkpoint:由master线程控制,每秒或每10秒刷入一定比例的脏页到磁盘。
  2. flush_lru_list checkpoint:从MySQL5.6开始可通过 innodb_page_cleaners 变量指定专门负责脏页刷盘的page cleaner线程的个数,该线程的目的是为了保证lru列表有可用的空闲页。
  3. async/sync flush checkpoint:同步刷盘还是异步刷盘。例如还有非常多的脏页没刷到磁盘(非常多是多少,有比例控制),这时候会选择同步刷到磁盘,但这很少出现;如果脏页不是很多,可以选择异步刷到磁盘,如果脏页很少,可以暂时不刷脏页到磁盘
  4. dirty page too much checkpoint:脏页太多时强制触发检查点,目的是为了保证缓存有足够的空闲空间。too much的比例由变量 innodb_max_dirty_pages_pct 控制,MySQL 5.6默认的值为75,即当脏页占缓冲池的百分之75后,就强制刷一部分脏页到磁盘。
  5. 对于每次commit操作的设置
    由于刷脏页需要一定的时间来完成,所以记录检查点的位置是在每次刷盘结束之后才在redo log中标记的。

关闭时的刷新:
MySQL停止时是否将脏数据和脏日志刷入磁盘,由变量innodb_fast_shutdown={ 0|1|2 }控制,默认值为1,即停止时只做一部分purge,忽略大多数flush操作(但至少会刷日志),在下次启动的时候再flush剩余的内容,实现fast shutdown。

日志位置:
在这里插入图片描述

写入流程:
在这里插入图片描述

可以设置几个组可以设置组里面有几个文件

类似于Java GC的操作原理
再次切换到文件1,检测其中哪些已经写入到数据库,然后擦除这部分日志中的记录,之后再开始写入
如果两个文件都已经写满,那么就会进行一次Major GC,将两个文件的数据同步到数据库中然后再向后执行
checkpoint就是去检查文件是否有空闲位置
在major GC执行时会停下数据库,不让数据继续进行提交,现将文件中的数据同步到数据库中,将文件擦除一部分然后再接受新的任务
在这里插入图片描述

日志与内存页刷盘

刷日志到磁盘有以下几种规则:

1.发出commit动作时。已经说明过,commit发出后是否刷日志由变量 innodb_flush_log_at_trx_commit 控制。

2.刷新时间设置:每秒刷一次。这个刷日志的频率由变量 innodb_flush_log_at_timeout 值决定,默认是1秒。要注意,这个刷日志频率和commit动作无关。

3.当log buffer中已经使用的内存超过一半时。

4.当有checkpoint时,checkpoint在一定程度上代表了刷到磁盘时日志所处的LSN位置。

被动刷脏页的时机:
Redo Log写满了, 需要将 checkpoint 向前推进, 以便继续写入日志
checkpoint 向前推进时, 需要将推进区间涉及的所有脏页刷新到磁盘.

内存不足, 需要淘汰一些内存页(最久未使用的)给别的数据页使用.
此时如果是干净页, 则直接拿来复用.

如果是脏页, 则需要先刷新到磁盘(直接写入磁盘, 不用管Redo Log, 后续Redo Log刷脏页时会判断对应数据页是否已刷新到磁盘), 使之成为干净页再拿来使用。

数据库系统空闲时
当然平时忙的时候也会尽量刷脏页.

数据库正常关闭
此时需要将所有脏页刷新到磁盘.

InnoDB需要控制脏页比例来避免Redo Log写满以及单次淘汰过多脏页过多的情况.

怎么将提交性能提升到最好

0、1、2的不同设置:都是1s,看怎么写
在这里插入图片描述

0:间隔1s将log buffer中的内容写入到OS buffer中,因为要操作底层磁盘,需要在内核空间中进行
问题:提交过程中宕机,还未写入到OS Buffer中,就会造成数据丢失,同AOF的写文件模式
1:安全性最高,性能比较差(默认)
2:数据也可能丢失

值为2和0的时候,它们的差距并不太大,但2却比0要安全的多:因为0在当前服务挂了(MySQL挂了)即不可用,而2只有在操作系统挂了之后才会丢失数据。它们都是每秒从os buffer刷到磁盘,它们之间的时间差体现在log buffer刷到os buffer上。因为将log buffer中的日志刷新到os buffer只是内存数据的转移,并没有太大的开销,所以每次提交和每秒刷入差距并不大。
更好的插入数据的做法是将值设置为1,然后修改存储过程,将每次循环都提交修改为只提交一次,这样既能保证数据的一致性,也能提升性能

还有刷盘时间的设置,设置刷新频率

WAL机制:

https://segmentfault.com/a/1190000020835301

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值