目录
binlog(归档日志)
介绍
- binlog 是 MySQL 的 Server 层实现的,
所有引擎都可以使用
- binlog 是
逻辑日志
, 记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ” - binlog 是可以追加写入的,“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并
不会覆盖以前的日志
三种格式对比
- statement:
- 记录执行的sql
- 可能会出现
主备不一致
的情况(例如插入时使用了Date函数)
- row:
- 记录每行的变更情况
- 很占空间
建议使用,便于数据恢复
- mixed:
- MySQL 自己会判断这条 SQL 语句是否可能引起主备不一致,如果有可能,就用 row 格 式,否则就用 statement 格式
写入文件机制
- 事务执行过程中,先把日志写到 binlog cache
- 事务提交的时候,执行器把 binlog cache 里的完整事务写入到 binlog files 中,并清空 binlog cache
- 根据参数
sync_binlog
将binlog files的内容fsync到磁盘中
参数
- binlog_cache_size
- 一个事务的 binlog 是不能被拆开的,因此不论这个事务多大,也要确保一次性写入
- 系统给 binlog cache 分配了一片内存,
每个线程一个
,参数 binlog_cache_size 用于控制单个 线程内 binlog cache 所占内存的大小。如果超过了这个参数规定的大小,就要暂存到磁盘。
- sync_binlog
- 0,只 write,不 fsync
- 1,只 fsync
- N,表示每次提交事务都 write,但累积 N 个事务后才 fsync
- 因此,在出现 IO 瓶颈的场景里,将 sync_binlog 设置成一个比较大的值,可以提升性能。在实际的业务场景中,考虑到丢失日志量的可控性,一般不建议将这个参数设成 0,比较常见的是将 其设置为 100~1000 中的某个数值,但是,将 sync_binlog 设置为 N,对应的风险是:如果主机发生异常重启,会丢失最近 N 个事 务的 binlog 日志
redo log
介绍
- redo log 是 InnoDB 引擎
特有
- redo log 是物理日志,记录的是
在某个数据页上做了什么修改
- redo log 是
循环写
的,空间固定会用完 - redo log 主要节省的是随机写磁盘的IO消耗(转成顺序写)
写文件流程
- 从头开始写,写到末尾就又回到开头循环写
- wirte pos是当前记录的位置,一边写一边后移
- checkpoint是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件
- checkpoint的前面是已经同步到磁盘的数据
- 当write pos追上checkpoint的时候,代表文件已满,不能再更新,需要先同步一波数据,后移checkpoint
刷脏页
- 当我们要往数据库插入一条数据、或者要更新一条数据的时候,我们知道数据库会在内存中把对应字段的数据更新了,但是更新之后,这些更新的字段并不会马上同步持久化到磁盘中去,而是
把这些更新的记录写入到 redo log 日记中去,等到空闲的时候,在通过 redo log 里的日记把最新的数据同步到磁盘中去
- 当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为
脏页
。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为干净页
刷脏页有下面4种场景(后两种不用太关注“性能”问题):
- redolog写满了: redo log 里的容量是有限的,如果数据库一直很忙,更新又很频繁,这个时候 redo log 很快就会被写满了,这个时候就没办法等到空闲的时候再把数据同步到磁盘的