mysql日志生成的过程_innodb的logs:生成过程

这篇是25号参加互动出版和北京GDG举办的数据库分享会的个人总结。Qunaer的王竹峰先生分享了他对innodb的log的认识和总结,主要包括了下面部分:innodb日志生成,日志文件/格式,redo、undo、doublewrite。

innodb的日志

mysql server的日志包括:bin-log(二进制日志),relay-log(中继日志),slow-log(慢查询日志),log(查询日志),error-log(错误日志)。

innodb的日志除了上面五种类型,为了实现事务,提高io性能,增强数据安全,其他原因,增加了下面日志机制:log_buffer,log_file,redo log,undo_log,重点是这一部分。

innodb的日志生成

名词解释:

(1)checkpoint,最近一次被修改的page成功flush磁盘时候的lsn,需要了解:

1)每次数据页有变化并被flush进磁盘的时候,都会产生一个checkpoint。

2)innodb将修改页从buffer pool刷进data file的时候,是一批操作,而不是一次写入。

3)checkpoint采用Fuzzy Checkpoint,即每次取最早的dirty page,确认此page之前的page都已经刷入磁盘,以此page的lsn为checkpoint的点。

4)checkpoint被记录在logfile开始的固定偏移位置上,并覆盖之前的checkpoint点。

(2)lsn,在mysql中是log sequence number的缩写。

1)lsn在mysql 5.6.3以前是一个4字节的无符号整数,最大值是2^32,5.6.3及以后为8字节无符号整数,最大值为2^64。

2)实例初始化时刚创建时lsn为0(当时还没有ib_logfile),以后就按照写入的内容大小来增长,lsn=前1个lsn值+增量;

3)ib_logfile每次增长512字节。

4)操作写入log buffer时,产生新的lsn。

5)每次写入log buffer时,确认log buffer剩余空间是否够存放,不够,则把buffer里的内容刷入logfile。并更新log buffer的lsn,logfile的lsn。

(3)undo_log是待修改的原数据的一个备份,存放在共享空间ibdata中中的。当事务执行失败或rollback的时候,用undo_log将数据恢复到执行之前。

undo_log记录的是完整的page还是待修改的数据行?是完整的page。

(4)redo_log事务日志,是对数据修改操作的备份,存放在ib_logfile*文件中,由innodb_log_file_size,innodb_log_files_in_group,innodb_log_group_home_dir三个参数定义,当然还有其他的参数。假设如下设置:

innodb_log_file_size=256M

innodb_log_files_in_group=3

定义了三个ib_logfile文件,logfile编号从0开始,每个大小256M,那么redo_log会按照下面顺序来日志:

fd057944cc519585e16b5f7bde715da6.png

先写入log_file0,之后logfile1,再满logfile2,再慢覆盖写logfile0,如此循环。

logfile的每次操作以512字节对齐。

redo_log记录的是什么?不是page,不是操作,是一种称作“生理”日志的记录,它的结构如下:

Type

spaceid

offset

data

Type:日志记录类型,1字节。最高位!

Space:表空间,compressed整形,1-5字节!

Offset:页号,compressed整形,1-5字节

Data: 根据不同的TYPE有不同的格式!

(5)undo的redo_log

innodb在修改page之前,会将数据行存放进undo_log空间,并且将这个操作记录进log_buffer,被存入redo_log,这个操作就是undo的redo_log。此操作被计入mtr中。在logfile中记录如下:

记录1: >记录2:记录3:>记录4:记录5:>记录6:

(6)Miti-Transcation(MTR)

mysql操作的最小单元是数据页,每个操作可能是一个page或者n个page的连续操作,这些操作被包含在mtr中。mtr是在1或n个page上操作的集合,具有不可分割性,一致性。

1)一致性。在n个page上的操作不可分割时,这些page的操作记录被包含在同一个mtr中,一起被提交到redo log buffer。InnoDB在redo log的层面,将一个MTR中的所有日志作为Redo log的最小单元。在恢复时,一个MTR完整才能进行操作。

2)mtr的封装。如果一个mtr只对一个page操作,并且只有1行记录,那么在mtr开始添加MLOG_SINGLE_REC_FLAG;如果一个mtr有n行记录,则在mtr结尾添加MLOG_MULTI_REC_END。

3)一个mtr被提交到log_buffer后,mtr相关的page获取同一个lsn,并且这些page被加入buffer_pool的flush_list。

4)mtr加的page_lock确保同一个page同时只能被一个mtr访问。mtr提交之后(被计入log buffer),page锁被释放,锁类型包括mtr_s_lock或mtr_x_lock。

5)mtr不能回滚,只能提前预判执行会不会失败。

redo-log生成的流程,请看下图:

235c6bc1e5f440f81d78413bcb566d29.png

注:图是我自己查资料画的,肯定有很多不对的地方,尤其红色部分,自己没有确认过。

这个过程有4个lsn:

lsn1:mtr计入log_buffer的时候,对log_buffer的lsn进行更新。这个lsn也是mtr对应脏页上的lsn

lsn2:log_buffer刷进redo_log的时候,对redo_log的lsn进行更新。

lsn3:Dirty page被flush进datafile的时候,更新对应data page的lsn。

lsn4:在log_file中产生的CKP(checkpoint)的lsn。

同一时间点的这四个lsn有下面大小关系:lsn1 >= lsn2 >= lsn3 >= lsn4(ckp)

查看show engine innodb status\G;

---

LOG

---

Log sequence number 1632169

Log flushed up to 1632169Pages flushed upto 1632169Lastcheckpoint at 1632169

0 pending log writes, 0pending chkp writes8 log i/o's done, 0.00 log i/o's/second

lsn1~4分别对应这4行状态。看到这四个值相等,表示所有数据均已写入datafile,buffer_pool中没有脏页。

在mysql5.1中,没有data page刷新 Pages flushed up to 这一行。

Log flushed up在什么时候执行?

1)log_buffer剩余空间不足

2)master线程控制刷新

3)执行修改语句时检查,需要则刷新

4)生成CKP时

5)事务提交(由flush_log_at_trx_commit参数控制)

double_write

double_write,通过innodb_doublewrite参数控制,是在修改的page被刷入磁盘的时候,先将page写入存入一块预先分配好的连续的磁盘区,这块磁盘区大小为100个page,再从这个区域里将文件刷入硬盘。

这样有什么好处?防止page刷新进行到一半的时候,因为断电,机器故障等情况导致的partial-page-writes。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值