小米科技|一生挚友redo log、binlog《死磕MySQL系列 二》( 二 )


innodb_log_file_size设置太大 , 虽然极大地提高了 IO性能 , 但是在 MySQL重启或宕机时 , 恢复时间会因为 redo log文件过大而延长 。 而这种恢复时间通常是无法控制的 。
在设置合理的redo log大小和数量后 , Innodb能够保证 , 即使数据库发生异常重启 , 以前提交的记录也不会丢失 , 这一点也称为crash-safe 。
在这里 , 对crash-safe的理解先不提及它是什么 , 后面的文章会让你明白 。
二、如何根据项目情况设置innodb_log_file_size对于参数innodb_log_files_in_group设置3~4个就够用了 , 不用进行优化 。
着重讨论innodb_log_file_size的大小设置或优化设置 。
在 MySQL8.0之前 , 通常是计算在一段时间内生成的事务日志(redo log)大小 , 而 MySQL日志文件最小应承载一小时的业务日志量 。
此处的一段时间必须视自己的业务情况而定 , 外界有用1分钟的日志量也有1小时的日志量来计算 。
首先看一下 MySQL客户端的一个命令 pager , 在 MySQL日常操作中 , 通过设置 pager的显示方式 , 可以大大提高工作效率 。
目前 , 要查看 sequence在一分钟之内的值 , 您就可以执行 pager grep sequence , 它对mysql> show engine innodb status\\ G select sleep (60); show engine innodbstatus\\ G;返回的结果 。
禁止 pager设置执行 nopager , 如果不执行该命令 , 则只有等到下一次重新启动该命令才会失效 。

此处咔咔是在虚拟机上做的操作 , 可以看到一分钟内是没有任何操作 , 所以值前后相同 , 你可以在测试服务器做测试 。
这样计算出来的select (后边数据-前面的数据)/1024/1024*60 asMB_per_hour;值是一个小时后 redo log的大小
但是用这种方法计算一定是不合适的 , 在一分钟内业务繁忙或者业务空闲时间计算出的值都会产生较大误差 。
合适的方法是在一天中确定几个时间点 , 用一个脚本定时执行 , 然后记录相应的值 , 再取平均值 , 计算出的误差将减至最小 。
什么是 sequece?当每个 binlog生成时 , 该值从1开始 , 然后递增 , 每增加一个事务 ,sequenumber就加上1 。
二、binlog您可以从总体上了解到 MySQL架构分为两层 , 一个是 server层 , 另一个是存储引擎层 。
server层当然是负责功能方面的 , 而存储引擎层则负责处理与存储相关的操作 。
而且上面提到的redo log是Innodb存储引擎层特有的 , 其它存储引擎是不具备的 , 而server层也有自己的日志记录 , 就是将要聊到的binlog 。
redo log和binlog的区别
redo log是Innodb引擎特有的 , 而binlog是MySQLserver层特有的 , 所有引擎都可以使用 。
redo log是物理日志 , 它记录的是一条更新操作所做的修改 , binlog是逻辑日志 , 记录的是一条更新语句执行逻辑
redo log是循环写的 , 并且空间是固定的 , 比如上面配置4个1GB的redo log文件 , binlog是追加写的 , 这个文件写完了 , 换下一个文件 , 不会覆盖以前的日志 。 这也就是你经常看到只要你有完整的binlog文件就可以给你恢复到你想要的数据 。
MySQL为什么会有俩份日志呢?
在没有Innodb存储引擎之前 , MySQL默认存储引擎是MyIsam , 但MyIsam是没有重启恢复能力的 , binlog日志也仅用于归档 。
Innodb是另一家公司以插件的形式引入到Mysql , 既然binlog没有重启恢复的能力 , 那么我就使用redo log来实现重启恢复的功能 。
这就导致了当你使用Innodb存储引擎时会写俩份日志 。
三、什么是两阶段提交对redo log、binlog有了一定的认识后再来看看一条更新语句的执行流程 。
update user set age = age + 1 where id = 1;