PostgreSQL 初始数据库大小

Cad*_*nge 12 postgresql sql-server database-size fragmentation

我的问题有两个部分。

  1. 有没有办法在 PostgreSQL 中指定数据库的初始大小?
  2. 如果没有,当数据库随着时间的推移而增长时,您如何处理碎片?

我最近从 MSSQL 迁移到 Postgres,我们在 MSSQL 世界中创建数据库时所做的一件事是指定数据库和事务日志的初始大小。这减少了碎片并提高了性能,特别是如果事先知道数据库的“正常”大小。

我的数据库的性能随着大小的增长而下降。例如,我处理的工作负载通常需要 10 分钟。随着数据库的增长,这个时间会增加。执行 VACUUM、VACUUM FULL 和 VACUUM FULL ANALYZE 似乎不能解决问题。解决性能问题的是停止数据库,对驱动器进行碎片整理,然后进行 VACUUM FULL ANALYZE 使我的测试性能恢复到原来的 10 分钟。这让我怀疑是碎片化是导致我痛苦的原因。

我在 Postgres 中找不到任何关于保留表空间/数据库空间的参考。要么我使用了错误的术语,因此一无所获,要么在 Postgres 中有一种不同的方法来减轻文件系统碎片。

任何指针?

解决方案

提供的答案有助于确认我开始怀疑的内容。PostgreSQL 将数据库存储在多个文件中,这使得数据库可以增长而不必担心碎片化。默认行为是将这些文件与表数据一起打包,这对很少更改的表有好处,但对经常更新的表不利。

PostgreSQL 利用MVCC提供对表数据的并发访问。在此方案下,每次更新都会创建已更新行的新版本(这可能是通过时间戳或版本号,谁知道?)。旧数据不会立即删除,而是标记为删除。执行 VACUUM 操作时会发生实际删除。

这与填充因子有什么关系?表默认填充因子 100 完全填充表页,这反过来意味着表页内没有空间来保存更新的行,即更新的行将放置在与原始行不同的表页中。正如我的经验所示,这对性能不利。由于我的汇总表更新非常频繁(高达 1500 行/秒),我选择将填充因子设置为 20,即表的 20% 用于插入行数据,80% 用于更新数据。虽然这可能看起来过多,但为更新行保留的大量空间意味着更新行与原始行保持在同一页内,并且在 autovacuum 守护程序运行以删除过时行时表页未满。

为了“修复”我的数据库,我执行了以下操作。

  1. 将我的汇总表的填充因子设置为 20。您可以在创建时通过将参数传递给CREATE TABLE或事后通过 ALTER TABLE 来执行此操作。我发出了以下 plpgsql 命令:ALTER TABLE "my_summary_table" SET (fillfactor = 20);
  2. 发出 VACUUM FULL,因为这会写入一个全新版本的表文件,因此暗示会写入一个具有新填充因子的新表文件

重新运行我的测试,即使数据库达到我需要的数百万行,我也没有发现性能下降。

TL;DR - 文件碎片不是原因,而是表空间碎片。这可以通过调整表格的填充因子以适应您的特定用例来缓解。

Erw*_*ter 5

还有另一件事尚未进入您的方程式:HOT update。相关回答:

设置FILLFACTOR低至20 不会显得过大。它使桌子膨胀至其大小的五倍。如果 HOT 更新有效,您就不必那么低——通常

有例外:HOT 更新只能重用来自先前事务的死元组,不能重用来自相同并发事务的死元组。因此,繁重的并发负载或长事务重复更新相同的行可以保证如此低(甚至更低)的设置。

如果您有大的更新,一次更改表的大部分,您可能希望将它们分成几个块,理想情况下,一次只更改适合数据页本地的行数。但这很难估计和监管。

请注意,HOT 更新仅在更改的列以任何方式包含在索引中(既不作为数据也不作为部分索引中的条件)时才起作用。您可能会使用更新列上的索引阻止 HOT 更新。如果这些是可消耗的,那么没有它们,您可能会获得更好的整体性能。

最后,您可以为每个表设置autovacuum 参数。您可以使用激进的设置来定位大量更新的表,从而允许比仅FILLFACTOR 20.


Kub*_*aun 4

  1. 不,唯一接近的事情是当您使用 --with-segsize 开关编译服务器时,如果您的表占用的空间超过了一个演出,并且您的文件系统可以处理超过一个演出的单个文件,这可能会有所帮助。如果您插入 20 个演出,如果您不使用此开关,则必须创建 20 个文件。如果您的文件系统可以处理超过一个演出的文件,您只需将其设置为一个大值,很可能会看到一些好处,最坏的情况是一个小好处。

  2. 看看 CLUSTER http://www.postgresql.org/docs/9.1/static/sql-cluster.html和 FILLFACTOR http://www.postgresql.org/docs/9.1/static/sql-createtable.htmlhttp://www.postgresql.org/docs/9.1/static/sql-createindex.html

请注意,FILLFACTOR 可以应用于表和索引。