BinLog、RedoLog、UndoLog
1 BinLog
BinLog 是记录所有数据库表结构变更(例如 create、alter table)以及表数据修改(insert、update、delete)的二进制日志,主从数据库同步用到的都是 BinLog 文件。
BinLog 日志文件有三种模式。
format | 定义 | 优点 | 缺点 |
---|---|---|---|
STATEMENT | 只会记录可能引起数据变更的sql语句 | 日志量和io都消耗很低,性能是最优的 | 准确性差,对一些系统函数不能准确复制或不能复制,如now()、uuid()等 |
ROW | 记记录的是每行实际数据的变更StreamSets就要求该模式 | 可以绝对精准的还原,从而保证了数据的安全与可靠,并且复制和数据恢复过程是可以并发进行的 | 体积会非常大,同时对于修改记录多、字段长度大的操作来说,记录时性能消耗很严重。阅读的时候也需要特殊指令来进行读取数据。 |
MIXED | STATEMENT模式跟ROW模式的混合使用;一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式 | 准确性强,文件大小适中 | 有可能发生主从不一致问题 |
细节:对于绝大部分操作都使用STATEMENT模式来进行binlog的记录,只有以下操作使用ROW来实现:表的存储引擎为NDB,使用了uuid()等不确定函数,使用了insert delay语句,使用了临时表。
主从同步流程:
- 主节点必须启用二进制日志,记录任何修改了数据库数据的事件。
- 从节点开启了一个线程(I/O Thread)使用MySQL的协议以客户端的身份请求主节点的二进制日志文件数据,进行同步
- 主节点启用一个线程(dump Thread)处理从节点的请求,主节点检查自己二进制日志中的事件,跟从节点请求参数的位置比对,如果从节点的请求中没有该参数,则主节点从第一个日志文件的第一个事件一个一个开始发送给从节点
- 从节点接收过来的数据会放到中继日志(relay log)文件中,并记录该次请求的是主节点的哪一个日志文件的哪一个位置(主节点有多个日志文件)。
- 从节点启动另一个线程(sql Thread)用来从relay log中读取事件,并在本地执行。
MySQL的默认的复制方式是异步的,并且复制的时候有并行复制的能力。主库把日志发送到从库以后便不再负责,假如此时主库挂了,从库处理失败了,从库升级为主库,日志便丢失了
由此产生两个概念:全同步复制和半同步复制。
全同步复制:主库写入binlog后强制同步日志到从库,所有从库同步完成以后才返回给客户端,这种方式对性能产生严重的影响。
半同步复制:从库写入日志成功以后便发送一条ack消息通知主库,主库收到至少一个从库的消息后便认为写操作完成。
2 RedoLog
记录更新时InnoDB先将记录写入redolog,InnoDB会在系统空闲时将操作记录从redolog写入到磁盘,如果记录更新太多,就需要先将redolog中的一部分操作写入到磁盘,再记录redolog。
redolog有write pos和checkpoint
write pos:是当前记录位置,一边写,一边后移,写到第三个文件后便回到0号文件的开头,循环。
checkpoint:是当前的擦除位置,同样是往后推移并循环的,擦除记录之前要把记录写入到数据文件中。
有了redolog,InnoDB就可以保证数据库发生异常重启后,之前的提交记录都不会丢失,这个能力称之为crash-safe。
redolog的两阶段提交:为了让binlog跟redolog两份日志之间的逻辑一致,提交流程大致如下:写入redolog,状态为prepare--》写入binlog --》redolog 状态为commit
- 在2之前崩溃时系统重启发现没有commit则进行回滚。备份恢复:没有binlog。一致。
- 在3之前崩溃,系统重启发现没有commit,则进行commit。备份:有binlog,一致。
binlog和redolog的区别:
- redolog是由存储引擎InnoDB实现的,binlog是由MySQL的服务Server层实现的,所有存储引擎都可用。
- redolog是物理日志,记录的是某个数据页上做了什么修改;binlog是逻辑日志,记录的是语句的原始逻辑。
- redolog的使用空间的固定的,可以使用完,循环使用;binlog是追加文件,不会覆盖之前的日志。
3 undolog
undolog一般为逻辑日志,主要分两种:
insert undo log:代表事务在insert新记录时产生undolog,在回滚时需要,并且在事务提交之后可以立即被丢弃
update undo log:事务在update或delete时产生undolog,不仅在事务回滚时需要,在快照读时同样需要;所以不能随便删除,只有在快速读或事务回滚不涉及该日志时才会被purge线程统一清除