1. binlog:(在事务提交前写入;是MySQL服务层实现的,所有引擎都可以用,记录的是逻辑日志)
它是一种二进制日志,里面记录了对mysql数据库执行数据变更的所有操作,并且记录了发生时间,执行时长,操作数据等其他信息。但是它不记录select,show这种不修改数据的sql语句。binlog主要用于数据库恢复和主从复制以及审计操作。如果mysql数据库意外发生故障,可以通过biglog日志完成数据库中的数据恢复。
三种模式:
-
statement:该模式下记录的是数据库执行的sql语句,日志量小,可以减少磁盘的IO,可以提升存储和恢复的速度;但是在某些情况下会出现主从不一致的问题,比如now()函数。
-
row:该模式下记录的是每一行数据修改的细节,在进行批量操作时,会产生大量的日志;但是在主从复制和数据恢复时不会出现数据不一致的问题。
-
mixed:该模式是前两种模式的结合,它会根据执行的sql语句,在statement模式和row模式中选择一种记录到binlog中,默认使用的是statement模式。
2.redo log(是innodb引擎特有的,记录的是物理日志)
也叫重做日志,记录的是事务提交后数据页的物理修改,可以保证事务的持久性。
redo log 日志中记录了事务提交后对数据库的所有修改信息。
当事务提交后, buffer pool 中的数据页发生变化,这时还没有刷新到磁盘中的数据页称为脏页,脏页如果可以正常刷新到磁盘中,那么没redo log 什么事,如果服务宕机,脏页刷新失败,则会通过redo log 恢复数据。
3.undo log
也叫回滚日志,里面记录的是数据被修改前的信息(逻辑日志),比如delete一条记录,那么undo log中会记录一条对应的insert记录。当事务发生回滚时,可以通过逆操作恢复原来的数据。该日志可以保证事务的原子性和一致性。
相关问题:
能不能只用binlog 而不使用 redo log?
当mysql服务崩溃需要恢复数据的时候,binlog不能够很好的辨识需要恢复哪些数据。
我们需要恢复未写入磁盘但是写入biglog日志中的记录,虽然binlog中记录的是全量数据,但是当一条记录写入磁盘,另一条记录未写入磁盘时,binlog没有标识去判断哪些已经写入磁盘哪些没有,所以不管是两条记录都恢复到内存中还是都不恢复,结果都是错误的。
而redo log会将写入磁盘中的数据在redolog中抹除,这样数据库重启之后,只需要将redo log中的数据恢复到内存中就可以了。
Innodb是如何实现事务的?
Innodb是通过Buffer Pool,Log Buffer,Redo Log 和Undo Log实现事务的,以一个update语句举例。
-
当innodb收到一个update语句后,会先找到该数据所在的数据页,并将该页缓存在buffer pool中。
-
执行update语句,修改buffer pool中的数据。
-
针对update语句生成一个redo log对象,并存入log buffer中。
-
针对update语句生成undo log日志,用于事务回滚。
-
将修改信息写入binlog中,然后事务提交。
-
如果事务成功提交,那么就把redo log对象持久化,后续还有其他机制将buffer pool中的数据持久化到磁盘中。
-
如果事务回滚,则利用undo log日志进行回滚。