redolog对于事务提交后不丢失的意义
- 执行增删改sql语句时,针对一个表中的某些数据执行。首先必须找到这个表对应的表空间,然后是对应的磁盘文件,磁盘文件上面的数据页读取出来,放到buffer pool的缓存页里去。
- 在buffer pool里面更新缓存页的时候,更新链表,还有会专门的后台线程,不定时的根据flush,lru链表将缓存页刷回磁盘。
- 如果事务提交时,后台io线程还没有将缓存页刷回磁盘,mysql就宕机了。为了避免数据丢失,引入了redo_log机制,将修改的记录以日志的形式写入到redo_log文件中。这种日志大致格式:对表空间XX中的数据页XX中的偏移量为XX的地方修改了XX。这样就算宕机了,重启后也能根据redo_log恢复对缓存页的操作,择机重新刷回磁盘。
事务提交时将修改过的缓存页刷入磁盘和将操作写入日志文件,都是写入磁盘,差别在哪?1. 修改过的缓存页较大,日志文件可能就几个字节。 2. 缓存页刷入磁盘是随机写磁盘,性能很差;写redo_log顺序写入磁盘,很快。
redo_log长什么样
redo_log需要记录的就是表空间号+数据页号+偏移量+修改几个字节的值+具体的值
- 根据修改了数据页几个字节的值,redo_log分为不同的类型。MLOG_1BYTE(修改一个字节),MLOG_2BYTE(修改2个字节),如果修改很多字节MLOG_WRITE_STRING,代表在数据页的某个偏移量处插入一大串值。
- 日志格式:
日志类型(MLOG_1BYTE) 表空间ID,数据页号,数据页中的偏移量,具体修改的数据
redo_log_block
redo_log不是一条一条写入文件,通过redo log block
1.redo log block数据结构.一个redo log block有512字节,分为三部分,一个是12字节的header头,一个是496字节的body体,一个是4字节的trailer块尾.
2.12字节的header分为4部分.包括4字节的block_no,块唯一编号.2个字节的 data_length,就是block里写入了多少字节数据.
2个字节的first record group(这个block里第一组redo_log的偏移量);4个字节的checkpoint on.
3.redo log写日志其实是往redo log block里面写,写满一个redo_log_block后,将redo_log_block再写入磁盘文件。
redo_log_buffer
- redo_log_buffer是mysql在启动的时候,跟操作系统申请的一块连续的空间,用来缓冲redo_log写入的。
- 通过innodb_log_buffer_size可以指定这个redo_log_buffer的大小,默认16MB
- redo_log写入的顺序,先写入redo_log_buffer中的第一个redo_log_block,写入磁盘文件也是在文件中追加redo_log_block
- 执行事务的过程中,每个事务会有多个增删改查,会有多个redo_log,多个redo_log就是一组redo_log,每次一组redo_log都先在别的地方赞成,都执行完再把redo_log给写入到redo_log_buffer的block里去。如果一组redo_log很多,可能会存放在两个redo_log_block中。
redo_log_block什么时候刷入到磁盘文件里去
- 写入到redo_log_buffer的日志已经占据了redo_log_buffer总容量的一半了,会将内容刷回磁盘文件。
- 一个事务提交的时候,必须把他的那些redo_log所在的redo_log_block都刷入磁盘
- 后台线程定时刷新,有一个后台线程每隔1s就会把redo_log_buffer里的redo_log_block刷入磁盘。
- mysql关闭的时候,redo_log_block会刷入磁盘。
- redo_log文件写满了怎么办,redo_log写满了会有下一个redo_log,可以限制redo_log的文件个数,通过innodb_log_file_size可以指定每个redo_log文件的大小。