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

标签 postgresql

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

但我不确定是否遵循 scerio :-

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

我指的是 TOAST .以下段落有点不清楚:-

When a row that is to be stored is "too wide" (the threshold for that is 2KB by default), the TOAST mechanism first attempts to compress any wide field values. If that isn't enough to get the row under 2KB, it breaks up the wide field values into chunks that get stored in the associated TOAST table. Each original field value is replaced by a small pointer that shows where to find this "out of line" data in the TOAST table. TOAST will attempt to squeeze the user-table row down to 2KB in this way, but as long as it can get below 8KB, that's good enough and the row can be stored successfully.

为什么要讨论 8K 和 2K 两种尺寸?为什么 postgres 检查阈值 2K?

提前致谢。

最佳答案

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

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

想法是减小大小,使得一行不会占用表 block 中超过四分之一的空间。但是,如果失败,并且该行在 TOASTing 后最终大于 2KB,那也没有问题,只要生成的行适合一个 8KB 的 block 。

表行始终存储在单个表 block 中。如果任何现有 block 中没有足够的空间,则会分配一个新的表 block ,并为现有 block 留下一些空白空间.此空白空间仍可用于其他较小的新行。

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

关于postgresql - 当行大小超过页面中可用的可用大小时,postgres 如何在页面中存储行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49625778/

相关文章:

sql - Ruby on Rails - 具有连接和顺序的范围

Postgresql - 如何安全地重命名表

postgresql - 从 jsonb 数组包含具有特定属性的元素的表中选择

postgresql - Odoo服务器重启错误

mysql - 如何在 CakePHP3 中运行事务,同时检索最后的插入 ID 并同时适用于 PostgreSQL 和 MySQL?

postgresql - 在 PostgreSQL 中显示带有 NULL 的完整日期范围

sql - 如何在没有子查询的情况下依赖 DISTINCT ON

sql - 将最流行的值获取到数组类型中

SQL 计算项目状态历史记录在日期范围内的项目项

SQL - 如何从两个表中获取数据