首先说下undolog:
undo log的主要作用是用作事务的回滚和实现mvcc功能,因为mvcc的问题,需要对undolog随机读
user表中原纪录为
id | name |
1 | xiaoming |
这个时候执行一个sql update user set name = ‘xiaohong‘ where id = 1; 这个时候生成的undolog是逻辑变更,大概是update user set name = ‘xiaoming‘ where id = 1
undolog用来保证事务的一致性,在事务回滚的时候会查询对应的undolog,进行回滚。
undolog分为两种,一种是insert undolog,这种是插入语句对应的的undo log,他不会被作为mvcc,于是在提交之后这个log直接释放。
还有另外一种就是update undolog 这种是会以用于mvcc的,于是这种undolog 是会用链表串起来的,知道没有开启的事务早于当前undolog的创建时间,这个时候这个undolog就可以删除了
redolog
redolog用来保证事务的原子性和持久性
数据库运行阶段不需要读redolog进行读取。 所有线程公用一份redolog buffer。 在事务执行期间,redolog是记录在redolog buffer中的
innodb_flush_log_at_trx_commit参数会决定redo log刷盘的频率,如果是设置为1,那么每次commit都会刷盘(最好设置成这样),innodb master会每秒调用 write 写到文件系统的 page cache,然后调用 fsync 持久化到磁盘。
还有两种情况是会主动刷盘:
1、redolog buffer占用超过innodb_log_buffer_size的一半,就会write到page cache中
2、事务提交的时候会把redo log buffer持久化到磁盘
因为两阶段提交是 redo log 先 prepare, 再写 binlog,最后再把 redo log commit
所以redo log 在 prepare阶段 就要先write并fsync
redolog buffer在提交的时候里面可能包含了多个事务的redolog,所以一次性fsync的事务越多越好,那么就有了一个优化
这里的红色块是在一个队列中,头trx是事务,然后会遍历redolog buffer进行write,然后由leader进行fsync
我们理解的事务两阶段提交是 redolog prepare -> binlog 写入磁盘 -> redolog commit
redolog prepare 的时候需要写redolog,其实分为两步 redolog wirte和redolog fsync
binlog的写盘也是分为两步 binlog wirte 和 binlog fsync
所以最终你以为的事务提交过程是 redolog wirte -> redolog fsync -> binlog wirte -> binlog fsync
但是实际上这里做了一个优化,就是redolog希望尽可能晚的进行组提交, 就可以减少fsync的次数
binlog 其实是数据库server层的日志,一般用作主从同步和数据恢复,数据格式有statement、row、还有mixed
statement是sql格式的,row记录了行的变更(从什么到什么),mixed是这两种的混合形式
binlog是在两阶段提交 preparre 和 commit之间,也是要先write到page cache(文件系统缓冲区),然后调用fsync进行刷盘