参考:https://blog.csdn.net/luokn1995/article/details/108371825
binlog
概述
记录数据库执行的写入操作信息,以二进制的形式保存在磁盘中。binlog是mysql的逻辑日志,并且由Server曾进行记录,使用任何存储引擎的mysql数据库都会记录binlog日志。
使用场景
- 主从复制:在Master端开启binlog,然后将binlog发送到各个Slave端,Slave端更新数据;
- 数据恢复:通过mysqlbinlog工具恢复数据。
刷盘时机
mysql通过sync_binlog参数控制binlog的刷盘时机,取值范围是0-N:
- 0:不去强制要求,由系统自行判断何时写入磁盘;
- 1:每次commit的时候都要将binlog写入磁盘;
- N:每N个事务,才会将binlog写入磁盘。
日志格式
binlog日志有三种格式,分别为STATEMENT、ROW和MIXED。
- STATEMENT:基于SQL语句的复制,每一条会修改数据的SQL语句会记录到binlog中。
- 优点:不需要记录每一行的变化,减少了binlog的日志量,节约了IO从而提高了性能
- 缺点:在某些情况下会导致主从数据不一致,比如执行sysdate()、sleep()
- ROW:基于行的复制,不记录每条SQL语句的上下文信息,仅需记录哪条数据被修改了。
- 优点:不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题
- 缺点:会产生大量的日志,尤其是
alter table的时候会让日志暴涨
- MIXED:基于STATEMENT和ROW两种模式的混合复制,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog
redo log
基本概念
redo log包括两部分:
- redo log buffer(内存中的日志缓冲),易失的
- redo log file(磁盘上的日志文件),持久的
记录过程
mysql每执行一条sql语句,先将记录写入redo log buffer,后续某个时间点再一次性将多个操作记录写到redo nlog file,这种先写日志,再写磁盘的技术就是WAL(Write-AHead logging,预写式日志)技术。
在OS中,用户空间(user space)下的缓冲区数据一般情况下是无法直接写入磁盘的,中间必须经过操作系统内核空间(kernel space)缓冲区(OS Buffer)。因此,redo log buffer下入redo log file实际上是先写入OS Buffer,然后再通过系统调用fsync()将其刷到redo log file中。
写入场景
- 数据页修改完成,脏页刷出磁盘,记录redo log
- 聚集索引、二级索引、undo页面的修改,记录redo log
写入时机
mysql支持三种将redo log buffer写入redo log file的时机,可以通过innodb_flush_log_at_trx_commit参数配置:
| 参数值 | 含义 |
|---|---|
| 0(延迟写) | 事务提交不会将redo log buffer中日志写入到OS Buffer,而是每秒写入OS Buffer并调用fsync()写入到redo log file中。也就是说设置为0时是每秒刷新写入到磁盘中的,当系统崩溃,会丢失1秒钟的数据。 |
| 1(实时写,实时刷) | 事务每次提交都会将redo log buffer中的日志写入到OS Buffer并调用fsync刷到redo log file中,这种方式即使系统崩溃也不会丢失任何数据,但是因为每次提交都写入磁盘,IO性能较差。 |
| 2(实时写,延迟刷) | 事务每次提交都仅写入到OS Buffer,然后是每秒调用fsync()将OS Buffer中的日志写入到redo log file。 |
undo log
基本概念
undo log有两个作用:
- 回滚
- MVCC
写入时机
- DML操作修改聚簇索引前,记录undo log
- undo log页面的修改,记录undo log
日志类型
- insert undo log
- update undo log
insert undo log是指在insert操作中产生的undo log,因为insert操作的记录,只对事务本身可见,对其他事务不可见。该undo log可以在事务提交后直接删除,不需要进行purge操作。
update undo log记录的是对delete和update操作产生的undo log,该undo log可能需要提供MVCC机制,因此不能在事务提交时就进行删除。提交时放入undo log链表,等待purge线程进行最后的删除。
:::info
purge线程的作用:清理undo页和清除page里面带有Delete_Bit标识的数据行。
在InnoDB中,事务中的Delete操作不会物理删除,而是标识操作即逻辑删除。
:::
demo
假设有A,B两个数据,值分为1,21. 事务开始2. 记录A=1到undo log3. 修改A=34. 记录A=3到redo log5. 记录B=2到undo log6. 修改B=47. 记录B=4到redo log8. 将redo log写入磁盘9. 事务提交
在InnoDB内存中,一般顺序如下:
- 写undo的redo
- 写undo
- 修改数据页
- 写redo
