前段时间,有读者问我:民工哥,我前几天去面试了,因为简历上说我精通MySQL。officer一直追着问:binlog,redolog呢,我想问就问,看得我一头雾水。..当时我也看我一头雾水,就笑着回他:哥,你工作3年了,连binlog和redolog都不知道,你应该't。..那么,今天民工哥就上次读者遇到的问题分享一下自己的相关知识,希望对后面准备面试或者正在研究这方面的读者有一定的帮助或者参考价值。如果您觉得文章对您有用,请不要吝啬您的观看和转发支持,打工的小哥,先谢谢了。首先,我们来看一个query/update语句流程图,本文将重点介绍executor<->storageengine之间的交互。mysql不会在每次数据变化时立即写入磁盘,而是先将修改的结果暂存在内存中,过一段时间后再将多次修改一次性写入磁盘,减少磁盘io和开销提高运行速度。Mysql使用WAL(write-aheadlogging)技术保证事务在同一个事务中。每当数据库修改数据时,将修改结果更新到内存后,会在redolog中增加一行记录“应该在哪个数据页上修改什么”,并设置该记录的状态为prepare。commit提交事务后,本次事务中redolog中添加的记录的状态会被设置为commit状态,然后当修改被放到磁盘上时,redo会被状态为commit状态的记录的修改iscommit在日志中写入磁盘。过程如下图所示。重做日志的记录方式是有固定大小的。在mysql中,可以通过修改配置参数innodb_log_files_in_group和innodb_log_file_size来配置日志文件的数量和每个日志文件的大小。Redolog采用循环写入的方式进行记录。写到末尾时,会回到开头循环写入日志。如下图,writepos表示日志的当前记录位置。当ib_logfile_4写满时,会从ib_logfile_1开始记录;相关记录被擦除,即writepos->checkpoint之间的部分是redolog的空部分,用来记录新的记录,checkpoint->writepos之间的部分是redolog的数据修改记录重做日志要放在磁盘上。当writepos追上checkpoint时,必须先停止记录,将checkpoint往前推,为新的log腾出空间。建议收藏以备后用!MySQL常见错误码说明有了redolog,当数据库宕机重启时,还可以通过redolog恢复还未落盘的数据,即已经提交的事务记录不会丢失。有了redolog,为什么还需要binlog?1、redolog的大小是固定的。日志上的记录被修改并放到磁盘后,日志将被覆盖,不能用于数据回滚/数据恢复等操作。2、redolog由InnoDB引擎层实现,并不是所有的引擎都有。基于以上,binlog必不可少1.binlog是由server层实现的,也就是说所有引擎都可以使用binlog日志。2、binlog是通过appending的方式写的。每个binlog文件的大小可以通过配置参数max_binlog_size来设置。当文件大小大于给定值后,日志会回滚,后续的日志会记录在新的文件中。3、binlog有两种记录方式。语句格式是记录SQL语句,行格式是记录行的内容。有两条记录,分别是更新前和更新后。Binlog和redolog必须一致。binlog中不允许有记录,redolog中不允许有记录,反之亦然。前面说过,在一个事务中,redolog有prepare和commit两种状态。所以在redolog状态为prepare时记录binlog,可以保证两个日志的记录是一致的。下图列举了各种情况来说明。下面来看看整个完整的流程图相关参数设置建议1.innodb_flush_log_at_trx_commit:设置为1,表示直接将每笔事务的redolog持久化到磁盘(注意这里指的是redolog日志本身),确保mysql重启后数据不丢失。2、sync_binlog:设置为1,表示直接将每笔交易的binlog持久化到磁盘(注意这里指的是binlog日志本身),保证mysql重启后binlog记录完整。
