PostgreSQL 的正确存储大小估计技术

Bru*_*aco 8 postgresql database-size scalability

我们正在为生产使用准备一个 PostgreSQL 数据库,我们需要估计这个数据库的存储大小。我们是一个在数据库管理方面缺乏专业知识的开发人员团队,因此我们正在研究、阅读手册并使用我们的一般信息技术知识来实现​​这一目标。

我们有实际数据要迁移到这个数据库,并对增长有一些粗略的估计。为了这个例子,假设我们估计每年增长 50%。

关键是:进行良好尺寸估计的一般正确技术是什么?

我们根据以下规则估算存储使用量。我们需要建议的主题用粗体文本标记。非常欢迎对整个过程的反馈:

  1. 估计每个表的大小
    1. 发现每一行的实际大小。
      • 对于具有固定大小的字段(如bigintchar等),我们使用文档中描述的大小
      • 对于具有动态大小的字段(如text),我们估计了字符串长度并使用了函数select pg_column_size('expected text here'::text)
      • 我们为PostgreSQL 内部使用的OID增加了 4 个字节
    2. 将每行的大小乘以估计的行数
    3. 我是否需要在这里考虑任何开销,例如行或表元数据?
  2. 估计每个表索引的大小
    • 不知道如何估计,这里需要建议
  3. 估计事务日志的大小
    • 不知道如何估计,这里需要建议
  4. 估计备份的大小(完整和增量)
    • 不知道如何估计,这里需要建议
  5. 对实际最小尺寸的所有估计求和

  6. 对 1 年后的最小规模的估计值 1、2 和 4 的总和应用 1.5 倍(增长 50%)的系数

  7. 应用 1.2 ~ 1.4(多 20% 到 40%)的总体系数来估计 5 和 6 以获得良好的安全裕度

我知道规则变得相当广泛。让我知道是否需要示例以更好地理解。

Dan*_*ité 5

对于第 1) 点,您需要阅读文档的存储页面布局章节,尤其要考虑行级元数据的HeapTupleHeaderData 布局表。

对于用户表,每行 4 字节的 OID 已过时。自 8.1 以来,PostgreSQL 默认不再拥有它们。现在,这是由控制default_with_oids配置参数或WITH(OIDS)条款CREATE TABLE

当数据的重要部分处于活动状态(经常更新)时,估计磁盘大小会更困难,因为 UPDATE 相当于插入新版本,然后删除旧版本,然后希望尽可能重用未使用的空间。这里还有用于表的填充因子存储选项(请参阅CREATE TABLE 中存储参数部分)

指数层面也存在膨胀。对于写入繁重的表,索引比其最佳大小大几倍的情况并不少见。

您可能需要了解一些有关VACUUM 的知识,以了解在您的特定使用中您可能受到表和索引膨胀的影响有多大。

事务日志的大小完全取决于对数据库的写入量。


Gre*_*ith 5

进行良好的大小估计的一般正确技术是模拟模式并用假数据填充表。generate_series 函数对此很有用。只是为了说明手动执行此操作的过程中的错误是如何填充的,对于您开始充实的 (1),您每行丢失了大约 24 个字节的标头信息,正如您在 (3) 中所怀疑的那样,并且没有OID 不再出现在常规表上。

估计索引大小更加困难。它们相对于数据的压缩程度取决于该数据的变化程度。由于 B 树索引的工作原理,它们甚至不会线性增长。随着时间的推移,在 UPDATE 和 DELETE 的工作负载下,您将获得比在 INSERT 上工作负载大得多的索引。除非您模拟工作负载并让它消化一些测试数据一段时间,否则很难用数字来说明这一点。

主数据库目录中的事务日志大小受 checkpoint_segments 参数限制。有关文档提供了一些估计大小的公式,最糟糕的情况是大小约为 16MB * 3 * checkpoint_segment。一旦它增长到这个大小并开始自我修剪,它就会被修复,并且与较大数据库中的其他所有内容相比,它通常是微不足道的。

如果您对数据库进行二进制备份,它将与数据库大小相同。增量数据通常存储为一系列 WAL 文件,这些是需要考虑调整大小的重要事务日志内容。WAL 格式太复杂,无法手动调整大小,并且它在很大程度上取决于 checkpoint_segments 等。同样,估计它的唯一好方法是运行模拟并查看运行期间产生了多少个 WAL 文件。

还可以进行基于文本的逻辑备份。这些有多大取决于您使用的数据类型。作为最简单的例子,文本格式将会变得更大,但数字格式比字符串格式增长得多。同样,最简单的估计方法是模拟一些数据,使用 pg_dump 将其保存为纯文本,并尝试进行推断。