1,redo

        InnoDB是以页为单位的管理存储空间,我们进行的增删查改操作的从本质上是访问页面。而数据库要求事务要求ACID,针对持久化的要求,提出了redo的日志满足实现数据的持久化的特性。例如数据库进行数据后修改后,该事务修改后的页面会被刷新到内存的缓冲区中的,并不保证修改后的页面不会被立即写入到磁盘中;未提交事务中的语言会有多个操作语言,可能会修改多个不连续的页,当系统发生错误时数据的没有直接的刷新到缓冲区的。

        为了让已经进事务提交后的数据修改后的数据 的能够永久失效,即使后来系统发生了错误能够实现持久化的有效。

        将事务执行的过程中产生的redo日志文件刷新到磁盘中有以下好处:

  • redo日志是顺序写入磁盘的:在事务的执行过程中,每执行一条语句,就可能产生的若干条日志,这些日志是按照生产的顺序写入磁盘的,就是进行顺序的I/O
  • redo日志占用的内存非常的小:在存储的表空间ID、页号、偏移量以及需要更新的值,需要的存储空间特别的小。

2,redo日志的格式

        redo日志本质上记录了一下事务对数据库进行的那些修改。

type

space ID       

page number

offseet

data

  • type:日志的类型
  • space ID:表空间ID
  • page number:页号
  • data:记录的redo中的具体的数据

3,简单redo日志

        简单之日的类型只需要在某个页面的某个的偏移量出修改几个字节值,具体修改的后的内容是什么,这个简单的redo日志称为物理日志,并且根据在页面中写入数据的多上划分了多种的类型。

  •         MLOG_1BYTE:表示在页面的某个偏移量中写入1个字节的redo日志类型
  •         MLOG_2BYTE:表示在页面的某个偏移量中写入2个字节的redo日志类型
  •         MLOG_4BYTE:表示在页面的某个偏移量中写入4个字节的redo日志类型
  •         MLOG_8BYTE:表示在页面的某个偏移量中写入8个字节的redo日志类型
  •         MLOG_WRITE_STRING:表示在页面的某个偏移量中写入字节序列

4,复杂redo日志

        有时执行一条语句会修改多个页面,包括系统数据和用户数据页面

5,Mini-Transaction(以组的形式写入redo日志)

        一条SQL语句执行的过程的中,可能会修改多个页面(系统表空间、聚簇索引、二级索引),在实行的过程中会产生的redo日志,划分为的若干格不可分割的组

  1. 更新Max RowID属性为一组,不可分割
  2. 向聚簇索引中插入一条记录为一组,不可分割
  3. 向二级索引中插入数据为医嘱,不可分可。
  4. 其他

        不可分割的含义:像一个的B+树中添加一个记录时,可能会发生以下两种情况:会出现乐观插入和悲观插入:

  •         乐观插入:该页面中剩余的空间足够充足,直接将记录的插入法哦的该页面中,然后记录的一条的mlog_comp_rec_inseet类型的日志
  •         悲观插入:该页面的插入的空间不足,需要分裂的页面,将原先数据的页的一部分复制到新的数据页,然后将记录插入进去,再讲叶子结点插入到叶子节点的链表中,最后在节点中添加一条目录项指向新创建的页面这个过程会产生很多的redo日志

redo日志原子性的实现:需要原子性操作的redo日志,在结束时追加一条的类型为mlog_multi_end的redo结尾.

6,redo日志写入的过程

        redo日志会被写入的到一个称之为的redo_log_block中,该页的大小为512字节,同样的redo_log不可能直接更新到磁盘中。而是直接的写入到一个缓冲区中,该区域中会不划分为众多的连续的block中,可以通过启动选项的innodb-log_buffer_size指定缓冲区的大小。

        向log_buffer中写入的过程是顺序写入的,因此需要的一个变量buf_free记录的此刻应该写在那个偏移量中。

        redo的写入是以的MTR作为一组写入到block中,在该MTR没有结束的时,会存储在一个的地方,同时事务会支持并发的,因此最终写入到的block中的MTR中也可能的多个事务进行交叉,而一个MRT可能占用多个界面。

redo log block 结构

一个block分为三个部分。页头,页尾还有的body,页头的占12字节,页尾IE占据8字节,body占据的496字节,日志的内容是写入到的body中 的

7,redo之日刷新的时机

        redo存在的内存中的log_buffer中的,总是需要刷新到的内存的磁盘中的,刷新到磁盘中有以下几个时机

  1.         log_buffer 中的空间不足是
  2.         事务进行提交时
  3.          后台服务的主线程刷线维护
  4.         正常关闭服务
  5.         做checkpoint时