redo日志和undo日志区别是什么?

我们都知道innoDb刷新数据到磁盘是通过页为单位来刷新的,那么总不能每次修改一条数据或者几条,就把整个页刷新到磁盘上,所以这时候redo日志的作用就是记录每条新增或者修改后的数据,在以后特定的时间flush到磁盘上。

Flush什么东西到磁盘呢?Flush那些修改之后的脏页,当redo日志满了之后,就会有限flush脏页到磁盘,来腾出redolog空间,这时候就会影响数据库的查询性能。刷新脏页的时机是mysql服务器空闲的时候,当系统内存不足的时候,当服务器正常关闭的时候,这时候就可能发生flush脏页而导致的,所以当sql查询语句突然过慢,可以排查下是否是在flush脏页。

言归正传,数据的增删查改,不会直接访问磁盘里的数据,会在mysql服务器启动的时候申请一个buffer pool size来存储这些数据,减少磁盘的I/O,当磁盘上的数据和buffer poolsize里的内存数据不同的时候,就是脏页,干净页就是相同,因为有了这个概念的存在,所以就有了刚申请时候的free链表,和flush链表,flush链表顾名思义就是放脏页的,还有lru链表,最后使用的数据,也是会flush脏页的。

Lru链表的作用是什么呢,为了减少磁盘刷新的频率,所以这里面会有热数据和冷数据的概念,是3比7,当数据量第一次访问的时候是直接放在冷数据的,只有在block_time超过这个设置的时间再次访问,才会进入热数据,这样的设计结果好处就是避免mysql的预读。

那么undo日志是干嘛的呢?他是记录需要回滚的数据,比如insert如果需要回滚,那么至少需要记录他的数据id,如果update操作需要回滚,至少要记录他修改前的数据,如果delete需要回滚,那么至少要记录他删前的数据,所以select没有undo日志。每一个数据结构都会有三个隐藏的列,row_id,这不是必须的,当表的主键或者唯一键不存在的时候才会出现row_id,还有两个必须的隐藏列,row_pointer和trx_id,一个是唯一的事务id,一个是回滚指针,回滚指针就会指向undo日志里回滚的数据页。

Undo日志的isert和delete和update是不同的,delete需要注意的,数据结构有个特定的old_roll_pointer,指向未删除之前的数据结构作用于恢复。

Update就更复杂点,会根据是否修改了主键来记录,如果没有修改主键,则会就地更新,不会更改索引树的和表空间结构来更新,如果修改数据的长度更改了也不能触发就地更新。更新主键的话,这时候会先deletemark操作数据,并不是真正的删除数据,delete mark是记录在头部信息的一个字段,为什么不是真正的删除,因为为了方便其他事务也会访问这个数据,这就是mysql的mvcc机制,之后再把他插入聚簇索引中,重新定义插入的位子。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后端从入门到精通

你的鼓励是我最大的动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值