1.redo日志
innodb是也页的形式来存储数据,我们在做增删改查的操作本身是在访问数据页,首先我们在访问一个页的时候或者创建一个页面的时候,通常情况都是现在都是buffer bool 缓存池里面在进行操作,但是我们要保证数据的持久性,就是一个数据在删除或者插入或者更新的时候,要永久保存在磁盘上,所以我们mysql为我们提出了redo log ,比如我出现一个场景,突然数据库崩溃了,内存中所有数据都没有,如何让数据恢复到之前打开数据之前的场景呢 ?
在我们所有修改前提下,我们对数据库的操作都是在事务的开始或者结束时产生,比如我们现在对数据库插入一条数据,这个时候就会产成一条redo日志 redo日志的机构是,type(类型),spaceid(表空间id)data(redo具体内容)pagenumber(页号) redo日志就具体记录了你插入的数据,当然还有会记录额外的一些信息,(比如当前记录的地址,上一条记录的位置,字段多少,占用空间等等,) 我们主要讲讲它什么情况下持久化到硬盘,和怎么重新恢复数据, 前面就说到我们在读写数据库的情况都是在内存操作,首先它会向系统申请一段联系的空间log buffer,
1.会在log buffer 空间不足的情况下就持久化,空间占到log buffer 一半的情况就会持久化
2.会在在正常关闭服务器的情况会持久化
3.后台都有一个线程会一直持久化,大约每秒一次,
4.在做checkpiont持久化操作 (chenkpiont设计到了到lsn的计算不说)
在服务器崩溃的时候会根据最后时间段的checkpionk的点来确定恢复的终点然后将所有的redo日志作为一个依次扫描恢复,首先会通过spaceid和 pagenumber计算出值,将所有redo日志放入哈希槽里面,因为对于统一页号的值放入一个哈希槽,进行顺序遍历,这个样子才不会出错,同一个页面的redo日志是通过时间来排序的,举个例子,假如通过创建时间来遍历的话。假如我现在插入 后删除,可能就会变成先删除后插入,通过哈希表的方式也是进一步提高恢复的数据,
2.undo日志
innodb的undo日志主要是用来保证事务的,mysql为了好让我们撤销一些记录而做出了一个撤销日志。撤销日志主要也是记载了增删改,查询是不会产生undolog日志,我们都知道在一个每一行的记录都会有一个记录头上有一个事务id ,每一个事务id都是唯一的,我在每次对数据库的操作都要保证原子性的操作,我们每次对数据库的增删改的操作都是会生成一个undo log日志,这里面的每次操作都是不一样的 1插入操作 :insert 就会生成一条日志,这条日志包含,nudo no (编号),类型 当前地址,上一条undolog 地址,当前占用的空间和大小,
2.删除操作: 我们删除的一条记录的时候,首先会把这条记录的表头上的delete_mark 由0变成 1,但是也不会把目前这条记录和垃圾链表合在一起,而是中间状态,当这个删除的事务提交后在把这一条记录移除到垃圾链表中,等待新的记录来在替换已有的垃圾链表
3.修改操作:修改操作是分几种情况,第一种没有修改主键就地修改生成记录,比如我们把字段为 ‘小王’ 修改为‘大王’,在utf_8字符集都是3个字节的情况下 就是直接生成undo log日志,第二种就是修改‘小王’为‘大大王’ 就会把之前记录直接删除掉,然后插入新的记录,假如修改主键那就也是直接删除原来主键,插入新的位置,毕竟主键索引是天然排序的,这时候就会产生两条undo日志
undolog日志也是通过页来组成的,然后页面进行双向链表排序,然后组成表空间段,然后在我们直接回滚段的操作来进行的 我们在mysql启动参数里面有一个配置 innodb_rollback_sements来设置回滚段,