8.5 环形缓冲区

在读写大表时,PostgreSQL会使用环形缓冲区(ring buffer) 而不是缓冲池。环形缓冲器 是一个很小的临时缓冲区域。当满足下列任一条件时,PostgreSQL将在共享内存中分配一个环形缓冲区:

  1. 批量读取 当扫描关系读取数据的大小超过缓冲池的四分之一(shared_buffers/4)时,在这种情况下,环形缓冲区的大小为256 KB
  2. 批量写入 当执行下列SQL命令时,这种情况下,环形缓冲区大小为16 MB
  3. 清理过程 当自动清理守护进程执行清理过程时,这种情况环形缓冲区大小为256 KB。

分配的环形缓冲区将在使用后被立即释放。

环形缓冲区的好处显而易见,如果后端进程在不使用环形缓冲区的情况下读取大表,则所有存储在缓冲池中的页面都会被移除(踢出),因而会导致缓存命中率降低。环形缓冲区可以避免此问题。

为什么批量读取和清理过程的默认环形缓冲区大小为256 KB?

为什么是256 KB?源代码中缓冲区管理器目录下的README中解释了这个问题。

顺序扫描使用256KB的环缓冲。它足够小,因而能放入L2缓存中,从而使得操作系统缓存到共享缓冲区的页面传输变得高效。通常更小一点也可以,但环形缓冲区必需足够大到能同时容纳扫描中被钉住的所有页面。