当行大小超过页面中的可用空闲大小时,postgres如何在页面中存储行?

时间:2018-04-03 08:44:59

标签: postgresql

我正在探索postgres的存储机制。我知道postgres使用页面结构(每个大小为8K)来存储行。一个页面可以包含多行。我也知道TOASTing是由postgres完成的,当行不能包含在给定的页面中时。

但我不确定如何关注scerio: -

  • 当前页面只剩下1K空间,新创建的行大小超过1K。在那种情况下,会发生什么?是否会为该行分配新页面,旧页面将有未使用的空间?或者,当创建另一行大小小于或等于1K的行时,旧页面的剩余空间将被占用?

我指的是TOAST。 para之后有点不清楚: -

  

当要存储的行“太宽”时(默认情况下其阈值为2KB),TOAST机制首先尝试压缩任何宽字段值。如果这不足以使行低于2KB,则会将宽字段值分解为存储在关联的TOAST表中的块。每个原始字段值都由一个小指针替换,该指针显示在TOAST表中找到此“out of line”数据的位置。 TOAST将尝试以这种方式将用户表行压缩到2KB,但只要它可以低于8KB,这就足够了,并且可以成功存储行。

为什么它说的是8K和2K两种尺寸?为什么postgres检查阈值2K?

提前致谢。

1 个答案:

答案 0 :(得分:3)

首先,我应该澄清“表格页面中的足够空间”与属性是否被TOAST的问题无关。

您引用的段落描述了 TOAST如何通过首先压缩值然后将它们“脱节”存储在TOAST表中来尝试减小超过2KB 的表行的大小。

这个想法是减小大小,使得一行不占用表块中空间的四分之一以上。但是如果失败了,并且在TOASTing之后行结束时大于2KB,那么这也没有问题,只要结果行适合一个8KB块。

表行始终存储在单个表块中。如果任何现有块中没有剩余空间,则会分配新的表块,并为现有块留下一些空白空间。这个空白区域仍可用于其他较小的新行。

表格块的8KB限制和TOASTing阈值的2KB的限制在某种程度上是任意的,并且基于经验。如果您准备重新编译PostgreSQL,可以更改它们(从PostgreSQL v11开始,您可以在使用initdb创建数据库集群时指定块大小),但我没有听到任何报告这是一个好主意