binlog 是 MySQL 的 Server层实现的,所有引擎都可以使用。
Binlog日志最重要的两个使用场景如下:
ROW 记录表的行更改情况,可以为数据库的恢复、复制带来更好的可靠性,但是二进制文件的大小相较于STATEMENT会有所增加
MIXED STATEMENT和ROW模式的混合。默认采用STATEMENT格式进行二进制日志文件的记录,但是在一些情况下会使用ROW格式。
业内目前推荐使用的是ROW模式,准确性高,虽然说文件大,但是现在有SSD和万兆光纤网络,这些磁盘IO和网络IO都是可以接受的。
redoLog 是InnoDB特有的
一般当MySQL更新数据时,有两种情况,追加数据或定位到已经存在的一条数据进行修改。
然而磁盘随机读写速度很慢,无法满足高IO操作的场景。
为了提高写入效率,一般我们可以先将数据写入内存,空闲时再批量刷入磁盘。
但是这样就产生了一个问题:内存中的数据不是持久化的,如果掉电,数据就会丢失。
为了解决数据丢失的问题,MySQL引入了redo log来解决这个问题。
对于非内存数据库,磁盘I/O操作是导致数据库性能低下的主要原因。
在数据量相同的情况下,使用WAL日志的数据库系统,可以成倍减少磁盘写入操作,大大提高了数据库磁盘I/O操作的效率,从而提高了数据库性能。
当需要更新记录时,InnoDB引擎先写redo log并更新内存。在适当的时候,例如当磁盘空闲时,将redo log数据刷新到磁盘。
redo log的大小是固定的 类似环形队列
MySQL一开始没有InnoDB引擎,MySQL自带的引擎是MyISAM,但是MyISAM没有处理崩溃恢复数据的能力,bin-log日志只是用来归档。
InnoDB后来作为插件添加,它实现了自己的日志系统来保护数据,防止崩溃丢失数据问题。
内容不同:redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”
不同级别:redo log只能和InnoDB引擎一起使用,而bin-log位于MySQL服务器级别,可用于所有引擎。
磁盘存储形式不同:redo log循环写入,bin-log是累积追加的,所以可以用于数据恢复或者主备同步
写入的时间不同:bin-log通常在一个事务提交时写入,而redo log会在不同的时间点写入,如每次事务提交时,通过另一个线程事务执行,或在刷盘时写入。(注意:未提交的事务redo log也可能被刷新到磁盘)
作用不同:redo log用于crash恢复,保证MySQL宕机不丢失数据;bin-log用于指定时间点恢复数据,保证服务器可以根据时间点恢复数据,另外bin-log也用于主从复制。
由于redo-log是在InnoDB层,而bin-log是在 Server 层,这样就引入了一个新的问题。
如果redo log写入成功,但是在bin-log写入磁盘之前,程序crash了,说明事务还没有提交,所以redo-log里写入的新数据是无效的。
重新启动数据库进行数据恢复会将redo-log数据恢复到磁盘,从而创建无效数据。
为了解决这个问题,引入了两阶段提交。
在第一阶段,redo-log写入并处于准备状态。Server层将bin-log数据保存到磁盘,然后执行器调用引擎的提交事务接口提交事务,把redo-log变更为已提交状态,更新完成。
通过两阶段提交协议保证了redo-log数据和bin-log数据的一致性。
评论