Veeupup / distributed-system-and-database

分布式系统和数据库
3 stars 1 forks source link

日志文件为什么要按block划分呢? #9

Open xffxff opened 3 years ago

xffxff commented 3 years ago

image 增加读取效率体现在?

Veeupup commented 3 years ago

我的理解,分成两点来说:

  1. 32KB是 Linux 系统默认页大小 4KB 的整数倍,可以在每次读取一个 block 的内容的刚好读取 page 的整数倍,也就是4倍,也不用考虑每次读取多长,不需要每次计算读取多长的数据
  2. 将日志按照 block 和 chunk 大小划分,每个 chunk 可以保存自己的 checksum 这些信息,可以分小块验证这部分日志文件是否合法有效(避免出现部分写),如果写入的时候部分写,那么最后的 log(一个或者多个 chunk,block) 就会失效,这个时候只需要根据 checksum 查看日志是否有效,不有效的话就舍弃掉;当然也可以整个日志文件做一个 checksum,但是这样的话,一旦部分写失效,整个日志文件也就失效了(不知道从哪里开始是合法有效的日志)
Veeupup commented 3 years ago

一条日志记录应该可能包含一个或者多个 chunk,尽量让一个 chunk 包含一条日志记录(Full),如果一条日志太大,可能会被 block 分开,在不同 block 中的同一条日志记录会用多个 chunk 描述,那么就需要给 chunk 打上标记,说明是 同一条 日志的不同部分(First,Middle,Last),同时 每个 chunk 都会计算自己的 checksum,为了保证每个chunk 的完整性(如果对不上就舍弃这个 chunk)

再来说为什么设置成 32KB 这个大小,redo log 在恢复数据库内容的时候是顺序读,所以说无所谓读取多大的数据,所以可以设置成尽可能大的大小,但是也不能太大,如果太大,某个 block 中的某个 chunk 太大,如果这个 chunk 被损坏,那么之后舍弃的内容就会比较多,这个 chunk 之后的内容都要被舍弃掉,和之后包含同一条日志的 chunk 都会被舍弃,所以32KB的大小是一个 trade off;如果太小,读取就要分很多次,如果太大,那么其中某个 chunk 如果损坏,之后这个 block 中的内容都不能再使用了,会造成一定的浪费(恢复数据的粒度减小)

xffxff commented 3 years ago

说的挺好的,但还是感觉引入chunk很绕,chunk就是指下面这个下面这个函数写入磁盘的东西吧 image

Veeupup commented 3 years ago

确实,在代码里的对应就应该是这里了 @XFFXFF