(1)回顾
    里面很多INSERT,UPDATE和DELETE语句都在更新缓存页里的数据,但是万一事务回滚,你必须有每条SQL语句对应的undo log回滚日志,根据回滚日志去恢复缓存页里被更新的数据。
    比如你执行了INSERT语句,那么你的undo log必须告诉你插入数据的主键ID,让你在回滚的时候可以从缓存页里把这条数据给删除了。
    如果执行了DELETE语句,那么你的undo log必须记录下来被删除的数据,回滚的时候就得重新插入一条数据,如果你执行了UPDATE语句,你必须记录下来修改之前的数据,回滚的时候就得把数据给更新回去。
    如果执行了UPDATE语句,那么你必须记录下来修改之前的数据,回滚的时候就得把数据给更新回去。

    (2)INSERT的undo log的类型是TRX_UNDO_INSERT_REC,这个undo log里包含如下: rec表示记录
    这条日志的开始位置
    主键的各列长度和值
    表id
    undo log 日志编号
    undo log 日志类型
    这条日志的结束位置
    主键的各列长度和值:插入一条数据必然有一个主键,如果你指定了一个主键,可能这个主键就是一个列,比如id之类的,也可能是多个列组成的一个主键,比如“id+name+type”三个字段组成的一个联合主键,也是有可能的。所以这个主键的各列长度和值就是插入的这条数据的主键的每个列,他的长度是多少,具体的值是多少。即使你没有设置主键,MySQL也会弄一个row_id作为隐藏字段做你的主键。
    表id: 插入一条数据必然是往一个表里插入数据的,是需要一个id的,记录下来是在哪个表插入的数据。
    undo log日志编号: 每个undo log日志都是有自己编号的,而在一个事务里会有多个SQL语句,就会有多个undo log 日志,在每个事务里的undo log日志的编号都是从0开始的,然后依次递增。
    undo log日志类型: 就是TRX_UNDO_INSERT_REC ,insert语句的undo log日志类型就是这个。
    38.jpg

    (3)最后
    有了上面的日志形式,剩下的事就好办了,如果在buffer pool 的一个缓存页里插入了一条数据执行了insert语句。然后写入上面一条undo log,现在事务回滚了,直接就把这条insert语句的undo log拿出来,然后在undo log里就知道哪个表里插入的数据,主键是什么,直接定位到那个表和主键对应的缓存页,从里面删除掉之前的insert语句插入进去的数据就可以了,这样就可以实现事务回滚的效果了。

    删除的新增,新增的删除,修改的改回去,但是需要把原本的数据记录在undo log日志文件里。需要能定位的该条数据在undo log的开始位置,结束位置,还有这条数据的id,表id,日志编号,日志类型。