博物馆网站建设情况说明,学校官网,网站建设与推广是什么意思,万户网络科技有限公司怎么样文章目录1.redo log的作用2.redo log的结构2.1.redo log 记录2.2.redo log block2.3.redo log buffer3.redo log buffer 刷盘1.redo log的作用
首先我们都知道#xff0c;执行增删改SQL语句的时候#xff0c;都是针对一个表中的某些数据去执行的#xff0c;此时的话#x…
文章目录1.redo log的作用2.redo log的结构2.1.redo log 记录2.2.redo log block2.3.redo log buffer3.redo log buffer 刷盘1.redo log的作用
首先我们都知道执行增删改SQL语句的时候都是针对一个表中的某些数据去执行的此时的话首先必须找到这个表对应的表空间然后找到表空间对应的磁盘文件接着从磁盘文件里把你要更新的那批数据所在的数据页从磁盘读取出来放到Buffer Pool的缓存页里去。
redo log可以保证我们事务提交之后如果事务中的增删改SQL语句更新的缓存页还没刷到磁盘上去此时MySQL宕机了那么MySQL重启过后就可以把redo log重做一遍恢复出来事务当时更新的缓存页然后再把缓存页刷到磁盘就可以了。
redo log本质是保证事务提交之后修改的数据绝对不会丢失的
那么有人会问了你事务提交的时候把修改过的缓存页都刷入磁盘跟你事务提交的时候把你做的修改的redo log都写入日志文件他们不都是写磁盘么差别在哪里
实际上如果你把修改过的缓存页都刷入磁盘这首先缓存页一个就是16kb数据比较大刷入磁盘比较耗时而且你可能就修改了缓存页里的几个字节的数据难道也把完整的缓存页刷入磁盘吗而且你缓存页刷入磁盘是随机写磁盘性能是很差的因为他一个缓存页对应的位置可能在磁盘文件的一个随机位置比如偏移量为45336这个地方。
但是如果是写redo log第一个一行redo log可能就占据几十个字节就包含表空间好、数据页号、磁盘文件偏移量、更新值这个写入磁盘速度很快。此外redo log写日志是顺序写入磁盘文件每次都是追加到磁盘文件末尾去速度也是很快的。所以你提交事务的时候用redo log的形式记录下来你做的修改性能会远远超过刷缓存页的方式这也可以让你的数据库的并发能力更强。
2.redo log的结构
2.1.redo log 记录
redo log里本质上记录的就是在对某个表空间的某个数据页的某个偏移量的地方修改了几个字节的值具体修改的值是什么他里面需要记录的就是 日志类型表空间ID数据页号数据页中的偏移量具体修改的数据
一条redo log中依次排列上述的一些东西这条redo log表达的语义就很明确了他的类型是什么类型就告诉了你他这次增删改操作修改了多少字节的数据然后在哪个表空间里操作的这个就是跟你SQL在哪个表里执行的是对应的接着就是在这个表空间的哪个数据页里执行的在数据页的哪个偏移量开始执行的具体更新的数据是哪些呢。有了上述信息就可以精准完美的还原出来一次数据增删改操作做的变动了。
2.2.redo log block
我们已经知道了redo log的记录样子我们可以想一下redo log就是按照上述格式一条一条的直接就写入到磁盘上的日志文件里去了吗
其实MySQL内有另外一个数据结构叫做redo log block大概你可以理解为平时我们的数据不是存放在数据页了的么用一页一页的数据页来存放数据。那么对于redo log也不是单行单行的写入日志文件的他是用一个redo log block来存放多个单行日志的。
一个redo log block是512字节这个redo log block的512字节分为3个部分一个是12字节的header块头一个是496字节的body块体一个是4字节的trailer块尾。在这里面12字节的header头又分为了4个部分。 要写入磁盘的redo log其实应该是先进入到redo log block这个数据结构里去的然后再进入到磁盘文件里如下图所示。
redo log数据——》redo log block——》redo log文件
2.3.redo log buffer
redo log到底是如何通过内存缓冲之后再进入磁盘文件里去的这就涉及到了一个新的组件redo log buffer他就是MySQL专门设计了用来缓冲redo log写入的。
redo log buffer其实就是MySQL在启动的时候就跟操作系统申请的一块连续内存空间然后里面划分出了N多个空的redo log block。mysql的innodb_log_buffer_size可以指定这个redo log buffer的大小默认的值就是16MB其实已经够大了毕竟一个redo log block才512字节而已每一条redo log其实也就几个字节到几十个字节罢了
redo log都是先写入内存里的redo log block数据结构里去的写满了一个redo log block就会继续写下一个redo log block以此类推直到所有的redo log block都写满。然后完事儿了才会把redo log block写入到磁盘文件里去的。 万一要是redo log buffer里所有的redo log block都写满了呢 那此时必然会强制把redo log block刷入到磁盘中去的
其实在我们平时执行一个事务的过程中每个事务会有多个增删改操作那么就会有多个redo log这多个redo log就是一组redo log其实每次一组redo log都是先在别的地方暂存然后都执行完了再把一组redo log给写入到redo log buffer的block里去的。
3.redo log buffer 刷盘
redo log block在什么时候会刷入到磁盘文件里去
如果写入redo log buffer的日志已经占据了redo log buffer总容量的一半了也就是超过了8MB 的redo log block在缓冲里了此时就会把他们刷入到磁盘文件里去一个事务提交的时候必须把他的那些redo log所在的redo log block都刷入到磁盘文件里去只有这样当事务提交之后他修改的数据绝对不会丢失因为redo log里有重做日志随时可以恢复事务做的修改后台线程定时刷新有一个后台线程每隔1秒就会把redo log buffer里的redo log block刷到磁盘文件里去MySQL关闭的时候redo log block都会刷入到磁盘里去
当然绝对保证数据不丢还得配置一个参数提交事务把redo log刷入磁盘文件的os cache之后还 得强行从os cache刷入物理磁盘。
最后给大家说一下redo log日志文件的问题我们都知道平时不停的执行增删改那么MySQL会不停的 产生大量的redo log block写入日志文件那么日志文件就用一个写入全部的redo log对磁盘占用空间越来越大怎么办
实际上默认情况下redo log都会写入一个目录中的文件里这个目录可以通过show variables like datadir’**来查看可以通过**innodb_log_group_home_dir参数来设置这个目录的。
然后redo log是有多个的写满了一个就会写下一个redo log而且可以限制redo log文件的数量通 过innodb_log_file_size可以指定每个redo log文件的大小默认是48MB通过innodb_log_files_in_group可以指定日志文件的数量默认就2个。
所以默认情况下目录里就两个日志文件分别为ib_logfile0和ib_logfile1每个48MB最多就这2个 日志文件就是先写第一个写满了写第二个。那么如果第二个也写满了呢别担心继续写第一个 覆盖第一个日志文件里原来的redo log就可以了。
所以最多这个redo logmysql就给你保留了最近的96MB的redo log而已不过这其实已经很多了毕 竟redo log真的很小一条通常就几个字节到几十个字节不等96MB足够你存储上百万条redo log 了
如果你还想保留更多的redo log其实调节上述两个参数就可以了比如每个redo log文件是96MB 最多保留100个redo log文件