阿粉这么贴心,肯定给你讲清楚了~
在 MySQL 中,特别是存储引擎使用的是 InnoDB 时,那肯定绕不过去两个概念:redo log (重做日志) 和 binlog (二进制日志)
简单点儿说:redo log 是 InnoDB 存储引擎层方面的日志,所以如果你使用的存储引擎不是 InnoDB 的话,那就根本谈不上 redo log
binlog 是 MySQL Server 层记录的日志,所以不管是用的什么存储引擎,只要是 MySQL 都是会有 binlog 的存在,在做 MySQL 主从复制的时候,利用的就是 binlog
那么,你有疑问嘛?为什么要有 redo log 和 binlog ,只用一个 log 不可以嘛?咱们详细来看看它们都分别做了啥
redo log
为什么要有 redo log ?
我们可以这样想,如果没有 redo log 的话, MySQL 是如何进行工作的 查询还好说,毕竟只是查询一下记录而已,并没有对数据进行更改
那如果是增加和更新操作呢?现在一条 update 语句过来,后面是不是一定会有限定条件,就比如现在要更新一条记录,把 A 的银行卡余额更新到 1k ,那这条语句是不是应该来个限定条件,类似
where userName = 'A'
,也就是说,一般 update 操作都伴随着查询的操作,得先找到这个人,然后再进行更新操作对吧
如果数据量比较小还好,很快就能找到并且更新完毕
但是如果数据量比较大,里面有一亿条数据,怎么办?而且更新操作肯定是要写到磁盘上去的,那这中间的 IO 成本呢?如果我有好几十条 update 语句先后更新呢?这样想的话,你就能想到,就这些操作,成本就高的不行,那能不能降低一下这些成本呢?
这就是 redo log 的作用
就是当有一条记录更新的时候, InnoDB 引擎就会先把记录写到 redo log 里面去,同时更新内存,这样就算是更新这条数据成功了
但是此时,它并没有更新到磁盘上去对吧?别担心, InnoDB 会在恰当的时候,把这条及记录更新到磁盘上去
这样的思想或者技术,有个专有名词: WAL 技术,也就是 WriteAheadLogging ,核心就是先写日志,再写磁盘
同样,这里面有个问题
redo log 不能一直写吧?如果更新操作一直写入到 redo log 中的话,不限制大小的话,可能服务器上的存储空间都被 redo log 给占满了
所以 InnoDB 的 redo log 是固定大小的,比如我们配置了一组 4 个文件,每个文件大小是 1GB ,那么它的操作可能就会这样:
能够看到,主要就是 write pos 和 checkpoint , write pos 比较好理解,它就是当前记录的位置,有需要记录的操作就从当前位置向后移,等把
ib_logfile_3
写完之后,就回到
ib_logfile_0
文件开头继续写
checkpoint 是当前要擦除的位置,就是 InnoDB 引擎不是会在恰当的时候,将这些操作进行持久化,更新到磁盘上去,那持久化之后的数据是不是就可以擦除了
write pos 和 checkpoint 之间的部分就是可以用来记录操作的部分,那么如果 write pos 和 checkpoint 相遇了怎么办?相遇了是不是说明这个时候分配的 redo log 大小用完了,那这时候就不能再进行更新操作了,必须停下来处理一下,将 checkpoint 往前推推才行
就是因为有了 redo log ,所以 InnoDB 才可以保证即使数据库发生了异常重启,也没关系,之前提交的记录都还在,只需要根据 redo log 里面的记录进行相应恢复就可以了
所以如果你和 DBA 比较熟的话,可以问问,咱们的 MySQL 是不是可以恢复到半个月内任意一秒的状态,如果对方回答是,别怀疑,他真的不是在吹牛逼
binlog