Mysql binlog和redolog 原创: 怀风 光明和黑暗互相吸引 5天前 binlog 文件 什么是binlog binlog 全称为 (binary log) ,记录了对MYSQL数据库执行的所有操作语句(不包括SELECT,SHOW这类操作,因为这类型的操作不会对数据本身做修改),但是如果操作本身没有对数据库进行修改,那么该操作也会被记录入数据库。 如下表:test idname 1test 执行如下sql,是不对test表做数据修改,但是也会记录该操作 update test set name = 1 where id = 2 binlog日志的作用 恢复:数据恢复需要binlog 复制:与恢复原理类似,主要用来做主从复制,master->slave 审计:用户可以通过二进制日志中的信息来进行审计,判断是否又对数据库进行注入攻击 binlog日志的格式 从mysql5.1以后,开始引入binlog_format参数用于设置binlog的格式 statement:记录逻辑sql语句(如果使用 read commited事务隔离级别,会出现类似丢失更新的现象,导致主从复制出现问题,由于事务未提交且没有gaplock锁 binlog日志在缓冲中未写入binlog文件,写入文件顺序是事务提交的顺序.可能会导致同步是否顺序不一致) row:不在记录简单的sql语句(能够解决statement在read committed事务隔离级别遇到问题,但是日志文件会变得更大) mixed:mysql默认会采用statement格式,但是在一些特定情况下会使用row(相当于两者混合,自适应使用) binlog日志的写入 在默认情况下,binlog日志并不是每次写的时候就同步到磁盘的(类似于缓冲写,先写缓存,在同步到磁盘),但是如果在此时数据库发生宕机,再会给恢复和复制带来一些问题,有些数据可能没写入binlog,导致最后一部分数据丢失,这个时候syncbinlog参数就可以解决这个问题,syncbinlog这个参数,代表每次缓存写多少次日志同步到磁盘,如果参数设为1,则不写缓存每次操作直接同步到磁盘,但是这样会对系统IO产生一定影响,但是设置为1同时还有一种影响,就是一个事务还未提交前已经将该条日志记录到了磁盘,如果这时候事务还没提交数据库就宕机了,再回复的时候,未提交的事务并没有回滚,就会出现问题,在这种情况下可以通过设置,innodbsupportxa=1来解决 这里可能有人会觉得开启binlog日志会对数据库性能有影响,但是在官方手册中标识,性能损耗只有1%,但考虑到可用性,数据的恢复和复制,这点性能的损耗还是可以接受的 redo log 文件 什么是redo log 记录了对MYSQL数据库innodb存储引擎,记录了innodb存储引擎的事务日志,用于恢复数据。每个innodb存储引擎至少有一个redo log文件组,每个文件组中至少有两个redo log文件,每个文件大小一致,并以循环写入的方式运行.并且redo log不是直接写到磁盘,是先写入redo log缓存,在刷盘到磁盘,当两个文件都写满的时候,会进行checkpoint,将文件1的内容抹除,如图 redo log 和 binlog的区别 这里可能大家会有疑问,binlog可以恢复,那么要redo log有什么意义呢 redo log 是innodb引擎特有的,binlog是mysql的server层实现的,所有引擎都可以使用 redo log 是物理日志,记录了在某个数据页的修改,binlog是逻辑日志,记录的是这条记录的修改逻辑 redo log 是循环写的,空间固定会用完,binlog是可以追加写入的,"追加写"是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志 redo log 的大小不宜设置的过大或者过小,过小的话会导致频繁的checkpoint导致性能抖动,太大则恢复会需要更长的时间 两阶段提交 为了保证恢复数据时的状态准确性,维护逻辑一致性,采用两阶段提交,例如一次更新数据,如图 根据binlog的特性,我们可以知道binlog是在事务提交前写入,如果事务还未提交的时候,这个时候binlog已经写入了,但是数据库发生了异常宕机,那么根据binlog来恢复,就会把未提交的事务给恢复到库中,造成脏数据,而采用两阶段提交,这个时候我们看到redo log处于prepare阶段,binlog已经写了日志 则可以对未提交事务的脏数据做处理,防止恢复的时候出现脏数据 如果redo log 里面的事务只有完整的prepare,则判断对应事务binlog是否完整存在,如果是,则提交事务,如果不是回归事务 redo log 的写入 通过设置参数innodbflushlogattrx_commit的值来控制将缓存中的redo log写入磁盘,0代表提交事务时,不将redo log写入磁盘,而是等每次主线程刷新,1和2的区别在于,1表示在commit的时候将redo log从缓存中同步到磁盘,即伴有fsync的调用,2表示将redo log异步写到磁盘,即写到文件系统的缓存中,因此不能完全保证执行commit的时候会一定写入磁盘,为了保证事务的ACID中的持久性,必须将此参数设置为1,也就是每当有事务提交时,必须保证日志写入磁盘 这里要注意,如果有两个事务,如果事务A提交,事务B只写了redo log那么事务B的redo log也会被刷到磁盘上 阅读原文 微信扫一扫 关注该公众号 更多内容vip可查看 |