RedoLog诞生史
# RedoLog诞生史
InnoDB
存储引擎是通过页为单位对数据进行访问,换句话说对数据库的所有操作都最终会作用到这个页上面。
但是,磁盘的运行速度远远慢于内存,所以在对这个页操作的时候需要将数据给整到内存中去,来加快增删改查的速度。
MySQL的设计者设计了了一个叫做Buffer Pool
的存储在内存中的数据结构,用于平衡存储介质和内存之间的速度差异:
写入时先写入
Buffer Pool
中,后刷到磁盘中读取时
Buffer Pool
中有完整数据,则直接返回Buffer Pool
中只记录了更改状态,则需要合并磁盘和Buffer Pool
Buffer Pool
中无数据,进入磁盘查找
但是,在这种情况下不错处理会有一个问题,在写入Buffer Pool
成功,但是刷写磁盘时可能由于断电导致没有刷成功,数据出现了丢失。
需要一个新的数据结构,在事务提交完成之前把事务所修改的页面都刷到磁盘中,但是这个简单粗暴的做法有些问题:
刷新一个完整的数据页太浪费了
InnoDB
中是以页为单位来进行磁盘IO,事务提交时需要将一个完整的页面从内存中刷新到磁盘。一个页面默认是16KB大小,只修改一个字节就要刷新16KB的数据到磁盘上显然是太浪费了。这种在存储系统中有个专有的名词 —— 写放大(Write Amplification)随机IO刷起来比较慢
一个事务可能包含很多语句,即使是一条语句也可能修改许多页面,事务修改的这些页面在物理磁盘上不相邻,每一次操作前都需要寻址,称之为随机IO
针对这两种方式也比较好解决:
刷新完成数据页浪费
那就记录被修改的位置,把修改了哪些东西记录一下就好,比如:
update test set a = 2;
将第0号表空间的100号页面的偏移量为1000处的值更新为
2
。随机IO刷起来比较慢
这个就更好解决了,把随机IO给弄成顺序IO,磁盘中开辟一块单独的连续空间,就直接写这片空间就好了。
那空间写满了怎么办?重写!
空间开辟: 0....100
写到100之后,重新从0开始写。只需要做个标记,如果写入的,已经被实实在在的刷到磁盘中了,则这块是可以重写的;否则,MySQL整体阻塞,免得数据出现异常
有了这些手段,即使MySQL重启崩溃了,也仅仅需要从这个顺序空间中将数据的操作给捞出来,进行回放重新更新一下数据页就好了。
这个手段,MySQL中已经有了,叫做redo log
redo
日志占用的空间非常小
存储表空间ID、页号、偏移量以及需要更新的值所需的存储空间是很小。redo
日志是顺序写入磁盘的
在执行事务的过程中,每执行一条语句,就可能产生若干条redo
日志,这些日志是按照产生的顺序写入磁盘的,也就是使用顺序IO。
- 01
- 以 root 身份启动 transmission-daemon12-13
- 02
- Debian系统安装qbittorrent-nox12-09
- 03
- LXC Debain12安装zerotier并实现局域网自动nat转发07-29