如何在 PostgreSQL 8.2(用于 Greenplum)中找到死元组(碎片)?
Posted
技术标签:
【中文标题】如何在 PostgreSQL 8.2(用于 Greenplum)中找到死元组(碎片)?【英文标题】:How to find dead tuples (fragmentation) in PostgreSQL 8.2 ( for Greenplum)? 【发布时间】:2017-01-10 08:58:42 【问题描述】:我想在 PostgreSQL 8.2 中查找表的死元组和活元组。我们刚刚开始使用基于 PostgreSQL 8.2 的 Greenplum MPP 数据库系统。
由于默认的 MVCC 架构,我们需要找到一个表的死元组并计划对它进行 VACUUM。
我知道了,如何在新版 PostgreSQL 中找到死元组。我已经分享了两篇关于此的文章。
PostgreSQL: How to check Table Fragmentation using pgstattuple module
PostgreSQL: Script to find total Live Tuples and Dead Tuples (Row) of a Table
谁能帮我解决这个问题?
提前致谢!
【问题讨论】:
如果是基于PostgreSQL 8.2的,应该有autovacuum。使用它而不是试图自己弄清楚。 感谢您的回复,是的,autovacuum 已经存在,但我有很多表,每个表的大小约为 150GB。所以我也需要手动活动。 如果表没有足够频繁地自动清理,请减少autovacuum_vacuum_scale_factor
。您甚至可以将其设置为零并将autovacuum_vacuum_threshold
设置为适当的高值。您甚至可以为不同的表设置不同的这些参数。
@Anvesh greenplum 提供了一个可以解决您的用例的视图。尝试从 gp_toolkit.gp_bloat_diag 中选择 *;此视图包含有关磁盘上表的实际大小和基于表统计信息的表的预期大小的信息。列“bdidiag”显示表中有多少膨胀。表膨胀是表数据文件中旧数据行使用的可用空间的累积。
@LaurenzAlbe 虽然 greenplum 是 8.2 的一个分支,但 autovacuum 已禁用。
【参考方案1】:
不要使用自动吸尘器。 Greenplum 不是 PostgreSQL,并且 autovacuum 在数据库中不起作用。我强烈建议不要使用 PostgreSQL 标记 Greenplum 帖子,因为您可能会得到不正确的信息。这就像发布一个关于 OSX 的问题并标记 BSD。
具有膨胀的真空堆表:
psql -t -A -c "SELECT E'VACUUM \"' || bdinspname || E'\".\"' || bdirelname || E'\";' FROM gp_toolkit.gp_bloat_diag WHERE bdinspname <> 'pg_catalog'" | psql -e
但是 Greenplum 中的大多数表都可能不是基于堆的,它使用 MVCC,而是使用“Append Optimized”或简称 AO。它使用可见性映射来隐藏已删除的行,并且文件更小,因此速度更快。它还允许对表进行压缩和面向列。
AO 表也需要维护,但与堆表不同,它有一个内置的压缩阈值,由 gp_appendonly_compaction_threshold GUC 控制。只需 VACUUM 所有 AO 表,如果隐藏行的百分比超过 10%,数据库将自动重建表。
Greenplum 仍然存在从 PostgreSQL 继承而来的冻结期问题。此脚本通常不会返回任何行,但在具有很长时间未触及的表的较旧安装中,您可能会开始清理表。
vacuum_freeze_min_age=$(psql -t -A -c "show vacuum_freeze_min_age;")
psql -t -A -c "SELECT E'VACUUM \"' || n.nspname || E'\".\"' || c.relname || E'\";' FROM pg_class c join pg_namespace n ON c.relnamespace = n.oid WHERE age(relfrozenxid) > $vacuum_freeze_min_age AND c.relkind = 'r'" | psql -e
当您使用它时,您应该安排analyzedb 定期分析所有表。示例:
analyzedb -d gpadmin -s tpcds
别忘了目录!
psql -t -A -c "SELECT E'VACUUM ANALYZE \"' || n.nspname || E'\".\"' || c.relname || E'\";' FROM pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid WHERE n.nspname = 'pg_catalog' AND c.relkind = 'r'" | psql -e
这会重新索引目录索引:
reindexdb -s
【讨论】:
我在问题发布后立即删除了 Postgres 标记,但 Anvesh 又将其添加回来,我不想发起编辑战 感谢 Jon,将检查此解决方案并回复您。还删除了 postgresql 标记。以上是关于如何在 PostgreSQL 8.2(用于 Greenplum)中找到死元组(碎片)?的主要内容,如果未能解决你的问题,请参考以下文章
postgresql??????????????????????????????SQL??????
8.1 shell介绍8.2 命令历史8.3 命令补全和别名8.4 通配符8.5 输入输出重定向