共计 1127 个字符,预计需要花费 3 分钟才能阅读完成。
不晓得你还记不记得《孔乙己》这篇文章,酒店掌柜有一个粉板,专门用来记录客人的赊账记录。如果赊账的人不多,那么他能够把顾客名和账目写在板上。但如果赊账的人多了,粉板总会有记不下的时候,这个时候掌柜肯定还有一个专门记录赊账的账本。
如果有人要赊账或者还账的话,掌柜个别有两种做法:
- 一种做法是间接把账本翻出来,把这次赊的账加上去或者扣除掉;
- 另一种做法是先在粉板上记下这次的账,等打烊当前再把账本翻出来核算。
同样,在 MySQL 里也有这个问题,如果每一次的更新操作都须要写进磁盘,而后磁盘也要找到对应的那条记录,而后再更新,整个过程 IO 老本、查找老本都很高。为了解决这个问题,MySQL 的设计者就用了相似酒店掌柜粉板的思路来晋升更新效率。
而粉板和账本配合的整个过程,其实就是 MySQL 里常常说到的 WAL 技术,WAL 的全称是 Write-Ahead Logging,它的关键点就是先写日志,再写磁盘,也就是先写粉板,等不忙的时候再写账本。
具体来说,当有一条记录须要更新的时候,InnoDB 引擎就会先把记录写到 redo log(粉板)外面,并更新内存,这个时候更新就算实现了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘外面,而这个更新往往是在零碎比拟闲暇的时候做,这就像打烊当前掌柜做的事。
如果明天赊账的不多,掌柜能够等打烊后再整顿。但如果某天赊账的特地多,粉板写满了,又怎么办呢?这个时候掌柜只好放下手中的活儿,把粉板中的一部分赊账记录更新到账本中,而后把这些记录从粉板上擦掉,为记新账腾出空间。
与此相似,InnoDB 的 redo log 是固定大小的,比方能够配置为一组 4 个文件,每个文件的大小是 1GB,那么这块“粉板”总共就能够记录 4GB 的操作。从头开始写,写到开端就又回到结尾循环写,如上面这个图所示。
write pos 是以后记录的地位,一边写一边后移,写到第 3 号文件开端后就回到 0 号文件结尾。checkpoint 是以后要擦除的地位,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。
write pos 和 checkpoint 之间的是“粉板”上还空着的局部,能够用来记录新的操作。如果 write pos 追上 checkpoint,示意“粉板”满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推动一下。
有了 redo log,InnoDB 就能够保障即便数据库产生异样重启,之前提交的记录都不会失落,这个能力称为 crash-safe。
要了解 crash-safe 这个概念,能够想想咱们后面赊账记录的例子。只有赊账记录记在了粉板上或写在了账本上,之后即便掌柜遗记了,比方忽然开业几天,复原生意后仍然能够通过账本和粉板上的数据明确赊账账目。