
事务处理与恢复
|
77
绕过内核的页缓存
很多数据库系统使用 O_DIRECT 标志打开文件。该标志允许 I/O 系统调用绕过内核
的页缓存直接访问磁盘,并使用数据库专用的缓冲区管理。
Linus Torvalds 批评过 O_DIRECT 的使用,因为它不是异步的,而且没有预读之类
的方法来告知内核有关访问模式的信息。但是,在操作系统提供更好的机制之前,
O_DIRECT 仍然很有用。
我们可以通过 fadvise 这个系统调用从某种程度上控制内核如何将页换出页缓存,
但这仅仅是让内核考虑我们的意见,并不保证它一定会发生。为了避免在执行 I/O
时发生系统调用,我们可以使用内存映射,但那样我们也失去了对缓存的控制。
5.1.1
缓存语义
所有对缓冲区的更改都保留在内存中,直到最终被写回到磁盘上。由于不允许任何其他
进程修改磁盘上的这些文件,所以这个同步过程是单向的:只能从内存同步到磁盘,而
不能反过来进行。页缓存让数据库能够更好地控制内存管理和磁盘访问。你可以将它视
作内核页缓存在应用程序中的等效实现:它直接访问块存储设备,实现类似的功能,也
达到了类似的目的。它是对磁盘访问的抽象,并将逻辑写操作与物理写操作分离。
页缓存使得我们可以将树部分保留在内存中,而无须修改算法本身或是在内存中物化对
象。我们要做的仅是把磁盘访问替换成对页缓存的调用。
当存储引擎访问(或请求)页时,我们首先检查其内容是否已被缓存。如果该页在缓存
中,则直接返回缓存的页。如果该页未被缓存,则页缓存会将其逻辑地址或页号转换为物
理地址,并将它的内容加载到内存,然后返回已缓存的版本给存储引擎。一旦返回,这个 ...