bin log
binlog文件记录了所有数据库表结构更改和编数据修改的日志。
与redo log的区别
- 适用对象不同:binlog是server层实现的日志,所有存储引擎都可以使用,而redo log是InnoDB实现的日志。
- 文件格式不同:binlog有三种格式,STATEMENT(默认),ROW,MIXED
- STATEMENT:记录了每一条修改数据的SQL
- ROW:记录了行数据修改陈干了什么样。
- MIXED:包含了 STATEMENT 和 ROW 模式,它会根据不同的情况自动使用 ROW 模式和 STATEMENT 模式
- redolog是物理日志,记录的是某个数据页做了什么修改。
- 写入方式不同:binlog是追加写,写满一个文件就创建新文件,不覆盖以前的日志,保存全量日志;redo log是追加循环写,日志空间大小是固定的,全部写满则从头开始写,保存未被刷入磁盘的脏页日志。
- 用途不同:binlog用于备份恢复、主从复制;redo log用于掉电等故障恢复。
主从复制的实现
依赖于binlog,复制的过程就是将binlog中的数据从主库传输到从库上,分为三个阶段:
- 写入binlog:主库收到客户端的事务提交请求后,先写入binlog,再提交事务,更新存储引擎中的数据,事务提交完成后,返回给客户端成功的响应。
- 同步binlog:从库会创建一个专门的IO线程,连接主库的log dump线程,来接收主库的binlog日志,再把binlog信息写入到 relay log的中继日志,再返回给主库复制成功的响应。
- 回放binlog:从库创建一个用于回放binlog的线程,去读relay log,然后回放binlog更新存储引擎中的数据,实现主从一致。
其他主从复制模型
- 同步复制:主库提交事务的线程要等待所有从库的复制成功响应才返回客户端结果。性能和可用性都很差;一是要等到所有节点都返回响应,二是主库和任何一个从库出问题都会影响业务。
- 异步复制:MySQL 主库提交事务的线程并不会等待 binlog 同步到各从库,就返回客户端结果。这种模式一旦主库宕机,数据就会发生丢失。
- 半同步复制:介于二者之间,只要有部分从库成功响应回来即可,主库事务线程就可以返回给客户端。这种半同步复制的方式,兼顾了异步复制和同步复制的优点,即使出现主库宕机,至少还有一个从库有最新的数据,不存在数据丢失的风险。
binlog的刷盘时机
事务执行时,会先把日志写入到 binlog cache,事务提交后再把binlog cache写入到binlog文件中。MySQL给每个线程分配了一片内存用于缓存binlog。
在事务提交时,执行器把binlog cache里的完整事务写入到binlog文件,然后清空binlog cache。
写入到page cache很快,但是执行fsync刷新到磁盘是很慢的,因此MySQL提供了sync_binlog参数控制刷新到磁盘的频率。
- 0:每次事务都只write,不fsync,交由操作系统进行刷盘。
- 1:每次事务都write然后fsync。性能比较低,但安全性高。
- N:每次事务都write,积累N个事务后执行fsync。