这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战
引言:众所周知mysql中主从复制是依靠日志实现的。说到日志mysql中有许多的日志,比如说:1.redo log 2.undo log 3.bin log 4.error log 5.slow query log 6.relay log。今儿就来谈谈mysql中的bin log、undo log 以及redo log。
bin log
mysql的主从复制利用了 bin log的特性,bin log还用于mysql数据恢复
bin log的刷机时间:mysql通过sync_binlog参数控制bin log的刷机时间,取值范围为0-N,其中:
-
0:不做强制要求,由系统自行决定何时写入;
-
1:每次提交事务的时候都会将bin log写入到磁盘;
-
N:每N个事务才会将bin log写入磁盘。实际运用中自行设置N的个数,牺牲一定一致性换取性能。 mysql 5.7.7后该参数默认设为1。
-
binlog:归属于mysql服务,bin log的作用主要是记录数据库的写入操作(INSERT/UPDATE/DELETE),但是不记录查询操作,bin log是mysql的逻辑日志,所谓逻辑日志就是指保存的是执行的sql语句。
-
bin log 可以指定max_bin_size参数来设置bin log文件大小,超过阈值后会生成新文件来保存日志。
-
bin log 的过期时间可以通过指定expire_logs_days的方式进行指定。
-
bin log有三种格式(STATMENT、ROW、MIXED),可以通过指定binlog_format的方式进行指定。
undo log
- undo log:数据库中的原子性基于undo log实现,undo log主要记录了数据的逻辑变化,比如一条insert语句对应一条delete的undo log,对于每个update语句,对应一条相反的update的undo log,这样发生错误时就能回滚到事务之前的数据状态,此外,undo log也是MVCC(多版本并发控制) 实现的关键。其归属于innodb存储引擎
redo log
mysql innodb中的持久性是通过redo log进行实现的。mysql中与磁盘交互的最小单位是页,mysql如果直接将数据页刷新到磁盘中会产生性能上的问题:
1.在改动很小的情况下将完整的页刷新到磁盘上会导致很大的资源浪费。
2.修改的数据可能不是连续的,也就是说该数据分布在不同页上,这样使用随机IO写入对性能也是一种浪费。
- redo log:在事务提交时,只记录修改的数据页(因为日志文件相对更小并且在物理层上是连续的),归属于innodb存储引擎
- redo log分为两个部分:内存当中的日志缓存(redo log buffer)和磁盘中的日志文件(redo log file),mysql每执行一条事务都会先记录到redo log buffer中,等到后续某个时间点再将多条记录刷新到redo log file,这种先写日志,再写磁盘的技术是**WAL(Write-Ahead Logging)**技术。
计算机操作系统中,用户空间下的缓冲区数据一般情况下是无法直接写入磁盘的,中间必须经过操作系统内核空间(kernel space)缓冲区(OS Buffer)。因此,redo log buffer写入redo log file实际上是先写入OS Buffer,然后再通过系统调用fsync()将其刷到redo log file中.
redo log与bin log的区别
bin log日志只用于归档,只依靠bin log是没有crach-safe能力的。但只有redo log也不行,因为redo log是innoDB特有的,且日志上的记录落盘后会被覆盖。因此需要bin log和redo log二者同时记录,才能保证数据库发送宕机重启时,数据不会丢失。