binlog与redo log
李羽秋
2023年10月23日 · 阅读 1,149
binlog与redo log
1. redo log
redo log叫做重做日志,是保证事务持久性的重要机制。当mysql服务器意外崩溃或者宕机后,保证已经提交的事务,确定持久化到磁盘中的一种措施。
为什么需要redo log
- 传统的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,这整个过程IO成本、查找成本都很高。而redo log使用了WAL技术,当有一条记录需要更新时,InnoDB就会先把记录写到redo log里,并更新内存,在一定时机时刷到磁盘中,减少了磁盘io读写,提高了访问速度。
- redo log主要的作用就是用于数据库宕机的恢复工作。
redo log写入机制
redo log是固定大小的,每一组4个文件,每个文件的大小是1GB。它有两个指针:
- write pos:记录当前写的位置,一边写一边往后移
- checkpoint:当前要擦除的位置,也是往后推移且循环的
write pos 与checkpoint之间空的部分用来记录新的记录,当write pos 与 checkpoint重合的时候,代表redo log满了,需要先进行记录擦除。
redo log刷盘时机
通过一个参数控制:innodb_flush_log_at_trx_commit
- 1:commit的时候进行刷盘:这也是最保险的,因为如果这个时候崩溃了代表没有commit成功,因此,也不用恢复什么数据。
- 2:commit的时候,只是刷新近os的内核缓冲区,具体的刷盘时机不确定。
- 0:后台线程,每s刷新一次到磁盘中。
2. binlog
binlog是二进制日志文件,记录了数据库所有执行的DDL和DML等数据库更新语句。它是Mysql级别的日志,即所有存储引擎都会产生binlog。
binlog作用
- 数据恢复:如果Mysql数据库意外挂了,可以利用binlog进行数据恢复,因为该日志记录所有数据库所有的变更,保证数据的安全性。
- 数据复制:利用一定的机制将主节点Mysql的日志数据传递给从节点,实现数据的一致性,所以binlog对于数据备份、主从等都起到关键作用。
刷盘策略
binlog刷盘时机由sync_binlog控制,默认为0。
- sync_binlog = 0:每次提交事务都只write,由系统自行判断什么时候执行fsync。(这种情况虽然性能得到提升,但是机器宕机,page cache里面的binlog会丢失。
- sync_binlog = 1:表示每次提交事务都会执行fsync,更加安全。
- sync_binlog = N:每次提交事务都write,等积累到N个事务后才fsync。
binlog格式
binlog格式分为三种:
- Statement格式:每一条会修改数据的sql都会记录在
bin log
中- 优点:不需要记录每一行的变化,减少了
bin log
日志量,节约了IO,提高性能。 - 缺点:比如sql中存在函数如now()等,依赖环境的函数,会导致主从同步、恢复数据不一致
- 优点:不需要记录每一行的变化,减少了
- Row:为了解决Statement缺点,记录具体哪一个分区中的、哪一个页中的、哪一行数据被修改了
- 优点:清楚的记录下每一行数据修改的细节,不会出现某些特定情况下 的存储过程,或function无法被正确复制的问题。
- 缺点:比如对
ID<600
的所有数据进行了修改操作,那么意味着很多数据发生变化,最终导致同步的log很多,那么磁盘IO、网络带宽开销会很高。
- Mixed:混合模式,即Statment、Row的结合版
3. redo log 与binlog区别
- redo log是InnoDB引擎特有的;binlog是Mysql的Server层实现的,所有引擎都可以使用
- redo log是物理日志,记录的是“在某个数据页上做了什么修改”;binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这一行的c字段加1”。
- redo log是循环写的,空间固定会用完;binlog是可以追加写入的。“追加写”是指binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
4. 一条更新语句的执行流程
- 执行器调用引擎接口写入新数据
- 引擎把更新操作记录到 redo log中,此时redo log为prepare状态
- 执行器生成这个操作的binlog,并写入磁盘
- 执行器调用引擎的事务提交接口,引擎把redo log的状态改为commit
5. 两阶段提交
两阶段提交是指将redo log拆成两个步骤:prepare和commit。
为什么需要两阶段提交
我们先来看看如果不使用两阶段提交,即要么先写完redo log再写binlog,要么先写binlog在写redo log这两种方式会有什么问题。
- 先写redo log,后写binlog:先写redo log后,binlog没写完宕机了。这时可以通过redo log来进行数据恢复。但是由于binlog没有写完就宕机了,等下次通过主从复制的时候,会发现binlog并没有数据,造成主从数据不一致。
- 先写binlog再写redo log:如果写完binlog后,redo log 没写完就宕机,这个事务就无效了。但是binlog日志有该记录,在通过binlog进行同步后也会造成数据不一致。
分类:
mysql
标签:
MySQL(new)