Innodb底层原理与Mysql日志机制深入剖析--重点笔记
一,redo log日志
1,写入磁盘过程
redo log 从头开始写,写完一个文件继续写另一个文件,写到最后一个文件末尾就又回到第一个文件开头循环写,如
下面这个图所示。

write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。
checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件里。
write pos 和 checkpoint 之间的部分就是空着的可写部分,可以用来记录新的操作。如果 write pos 追上
checkpoint,表示redo log写满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推进一
下。
二,binlog
binlog二进制日志记录保存了所有执行过的修改操作语句,不保存查询操作。如果 MySQL 服务意外停止,可通过二
进制日志文件排查,用户操作或表结构操作,从而来恢复数据库数据。
启动binlog记录功能,会影响服务器性能,但如果需要恢复数据或主从复制功能,则好处则大于对服务器的影响。
1,binlog 的日志格式
用参数 binlog_format 可以设置binlog日志的记录格式,mysql支持三种格式类型:
STATEMENT:基于SQL语句的复制,每一条会修改数据的sql都会记录到master机器的bin-log中,这种
方式日志量小,节约IO开销,提高性能,但是对于一些执行过程中才能确定结果的函数,比如UUID()、
SYSDATE()等函数如果随sql同步到slave机器去执行,则结果跟master机器执行的不一样。
ROW:基于行的复制,日志中会记录成每一行数据被修改的形式,然后在slave端再对相同的数据进行修
改记录下每一行数据修改的细节,可以解决函数、存储过程等在slave机器的复制问题,但这种方式日志量较
大,性能不如Statement。举个例子,假设update语句更新10行数据,Statement方式就记录这条update语
句,Row方式会记录被修改的10行数据。
MIXED:混合模式复制,实际就是前两种模式的结合,在Mixed模式下,MySQL会根据执行的每一条具
体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种,如果sql里有函数或一些
在执行时才知道结果的情况,会选择Row,其它情况选择Statement,推荐使用这一种。
2,binlog写入磁盘机制
binlog写入磁盘机制主要通过 sync_binlog 参数控制,默认值是 0。
为0的时候,表示每次提交事务都只 write 到page cache,由系统自行判断什么时候执行 fsync 写入磁
盘。虽然性能得到提升,但是机器宕机,page cache里面的 binlog 会丢失。
也可以设置为1,表示每次提交事务都会执行 fsync 写入磁盘,这种方式最安全。
还有一种折中方式,可以设置为N(N>1),表示每次提交事务都write 到page cache,但累积N个事务后
才 fsync 写入磁盘,这种如果机器宕机会丢失N个事务的binlog。
3,重新生成
发生以下任何事件时, binlog日志文件会重新生成:
(1)服务器启动或重新启动
(2)服务器刷新日志,执行命令flush logs
(3)日志文件大小达到 max_binlog_size 值,默认值为 1GB
4,根据文件位置标识和时间戳恢复数据
看源文档
三,为什么Mysql不能直接更新磁盘上的数据而且设置这么一套复杂的机制来执行SQL了?
因为来一个请求就直接对磁盘文件进行随机读写,然后更新磁盘文件里的数据性能可能相当差。
因为磁盘随机读写的性能是非常差的,所以直接更新磁盘文件是不能让数据库抗住很高并发的。
Mysql这套机制看起来复杂,但它可以保证每个更新请求都是更新内存BufferPool,然后顺序写日志文件,同时还能
保证各种异常情况下的数据一致性。
更新内存的性能是极高的,然后顺序写磁盘上的日志文件的性能也是非常高的,要远高于随机读写磁盘文件。
正是通过这套机制,才能让我们的MySQL数据库在较高配置的机器上每秒可以抗下几干甚至上万的读写请求

浙公网安备 33010602011771号