规划器使用的统计信息(pg_class更改)

本文探讨了PostgreSQL中pg_class表的reltuples字段更新机制,指出该字段不会实时更新,而是通过VACUUM、ANALYZE或DDL命令如CREATE INDEX等方式更新。同时介绍了如何手动触发更新以及统计信息的重要性。
今天测试pg_class系统表里的那个reltuples字段,可是插入数据以后他老是不自动更新,差异下文档如下描述。
为了性能不能每时每刻更新,手动可以使用“ VACUUM,ANALYZE,和几个 DDL 命令,比如 CREATE INDEX 更新”
======================================================
[quote]
[url]http://www.pgsqldb.org/pgsqldoc-cvs/planner-stats.html[/url]
统计的一个部分就是每个表和索引中的记录总数,以及每个表和索引占据的磁盘块数。 这个信息保存在 pg_class 的 reltuples 和 relpages 字段中。我们可以用类似下面的查询检索这些信息:

SELECT relname, relkind, reltuples, relpages FROM pg_class WHERE relname LIKE 'tenk1%';

relname | relkind | reltuples | relpages
----------------------+---------+-----------+----------
tenk1 | r | 10000 | 358
tenk1_hundred | i | 10000 | 30
tenk1_thous_tenthous | i | 10000 | 30
tenk1_unique1 | i | 10000 | 30
tenk1_unique2 | i | 10000 | 30
(5 rows)
我们在这里可以看到 tenk1 有 10000 行, 它的索引也有这么多行,但是索引远比表小得多(很正常)。

出于效率考虑,reltuples 和 relpages 不是实时更新的, 因此它们通常包含可能有些过时的数值。 它们被 VACUUM,ANALYZE,和几个 DDL 命令,比如 CREATE INDEX 更新。一个独立的 ANALYZE, 也就是没有和 VACUUM 在一起的, 生成一个reltuples 的近似数值, 因为它并没有读取表里的每一行。规划器将把 pg_class 表里面的数值调整为和当前的物理表尺寸匹配,以此获取一个更接近的近似值。

大多数查询只是检索表中行的一部分,因为它们有限制待查行的 WHERE 子句。 因此规划器需要对WHERE子句的选择性(selectivity)进行评估, 选择性也就是符合WHERE子句中每个条件的部分。 用于这个目的的信息存储在 pg_statistic 系统表中。 在 pg_statistic 中的记录是由 ANALYZE 和 VACUUM ANALYZE 命令更新的, 并且总是近似值,即使刚刚更新完也不例外。

除了直接查看 pg_statistic 之外, 我们手工检查统计的时候最好查看它的视图 pg_stats。 pg_stats 设计成更具可读性。 而且,pg_stats 是所有人都可以读取的, 而 pg_statistic 只能由超级用户读取。 (这样就可以避免非特权用户从统计信息中获取一些和其他人的表内容相关的信息。 pg_stats 视图是受约束的,只显示当前用户可读的表。) 比如,我们可以∶

SELECT attname, n_distinct, most_common_vals FROM pg_stats WHERE tablename = 'road';

attname | n_distinct | most_common_vals

---------+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
name | -0.467008 | {"I- 580 Ramp","I- 880 Ramp","Sp Railroad ","I- 580 ","I- 680 Ramp","I- 80 Ramp","14th St ","5th St ","Mission Blvd","I- 880 "}
thepath | 20 | {"[(-122.089,37.71),(-122.0886,37.711)]"}
(2 rows)

pg_stats 在 Section 42.43 里详细描述。

在 pg_statistic 李存储的信息的数量,特别是 给每个字段用的 most_common_vals 和 histogram_bounds 数组上的最大记录数目可以用 ALTER TABLE SET STATISTICS 命令设置, 或者是用运行时参数 default_statistics_target 进行全局设置。 目前缺省的限制是 10 个记录。 提升该限制应该可以做出更准确的规划器估计,特别是对那些有不规则数据分布的字段而言, 付出的代价是在 pg_statistic 里使用了更多空间,并且需要略微多一些的时间计算估计数值。 相比之下,比较低的限制可能更适合那些数据分布比较简单的字段。
[/quote]
[quote]22.1.2. 更新规划器统计

PostgreSQL 的查询规划器依赖一些有关表内容的统计信息用以为查询生成好的规划。 这些统计是通过ANALYZE 命令获得的,你可以直接调用这条命令, 也可以把它当做 VACUUM 里的一个可选步骤来调用。 拥有合理准确的统计是非常重要的,否则,选择了恶劣的规划很可能降低数据库的性能。

和为了回收空间做清理一样,经常更新统计信息也是对更新频繁的表更有用。 不过,即使是更新非常频繁的表,如果它的数据的统计分布并不经常改变,那么也不需要更新统计信息。 一条简单的拇指定律就是想想表中字段的最大很最小值改变的幅度。 比如,一个包含行更新时间的 timestamp 字段将是随着行的追加和更新稳定增长最大值的; 这样的字段可能需要比那些包含访问网站的 URL 的字段更频繁一些更新统计信息。 那些 URL 字段可能改变得一样频繁,但是其数值的统计分布的改变相对要缓慢得多。

我们可以在特定的表,甚至是表中特定的字段上运行 ANALYZE, 所以如果你的应用有需求的话,我们是可以对某些信息更新得比其它信息更频繁的。 不过,在实际中,这种做法的有用性是值得怀疑的。 从 PostgreSQL 7.2 开始, ANALYZE 是一项相当快的操作,即时在大表上也很快, 因为它使用了统计学上的随机采样的方法进行行采样, 而不是把每一行都读取进来。因此,每隔一段时间对整个数据库运行一便这条命令可能更简单。

提示: 尽管用 ANALYZE 按字段进行挖掘的方式可能不是很实用, 但你可能还是会发现值得按字段对 ANALYZE 收集的统计信息的详细级别进行调整。 那些经常在WHERE子句里使用的字段如果有非常不规则的数据分布, 那么就可能需要比其它字段更细致的数据图表.参阅 ALTER TABLE SET STATISTICS.

我们对大多数节点都建议在每天的低使用时段安排一次数据库范围的 ANALYZE: 这个任务可以有效地和每天的 VACUUM 组合在一起。 不过,这对那些表统计信息改变相对缓慢的节点可能会过于夸张, 而且少一些的 ANALYZE 也足够了。
[url]http://www.kuqin.com/postgreSQL8.1_doc/maintenance.html[/url][/quote]
<think>嗯,用户问的是Greenplum集群中每个segment节点的pg_class表内容是否应该保持一致。首先,我需要回忆一下Greenplum的架构。Greenplum是一个基于PostgreSQL的MPP数据库,数据分布在多个segment节点上。每个segment都有自己的系统表,比如pg_class,用来存储数据库对象的元数据。 用户可能是在遇到数据不一致的问题,或者在进行维护时注意到不同segment上的pg_class表内容有差异。他们想知道这些表是否应该一致,这可能涉及到系统表的同步机制,或者是遇到了一些错误,比如查询结果不一致,需要排查问题。 接下来,我需要确认pg_class表的作用。pg_class存储了表、索引、视图等对象的信息,比如oid、表名、所属模式等。在Greenplum中,每个segment都有自己的pg_class副本,因为每个segment存储了部分数据,所以有些对象的元数据可能只存在于特定的segment上。比如,分布表的元数据在所有segment上都有,但本地临时表可能只在对应的segment存在。 用户可能混淆了系统表的一致性和数据分布。需要解释的是,对于分布式表,系统表的某些字段(如reltuples)可能在各个segment上不同,因为它们存储了本地数据的信息。而全局一致的元数据,比如表结构定义,应该保持一致,否则会导致查询错误。 另外,用户可能遇到集群升级、备份恢复或节点故障后的不一致问题,这时候需要使用gpcheckcat工具来检查和修复系统表的一致性。需要提醒用户在进行维护时备份数据,并使用正确的工具来处理。 还要考虑用户的使用场景,可能是运维人员或DBA,在处理集群健康状态时需要了解系统表的一致性要求。需要强调哪些情况下不一致是正常的,哪些是需要修复的,以及如何检测和修复这些问题。 总结来说,用户需要明确pg_class表在Greenplum中的分布特性,理解不同情况下的一致性问题,以及如何维护和修复系统表。需要分点说明,结构清晰,让用户能够逐步理解并采取正确的操作。</think>在 Greenplum 分布式数据库中,**pg_class 表的内容在 Segment 节点间遵循特定的分布式一致性规则**,而非简单的完全一致。以下是关键点解析: --- ### **1. 基础认知** - **pg_class 表作用**:存储表、索引、序列等对象的元数据(如 `oid`, `relname`, `relnamespace`, `relkind` 等)。 - **Greenplum 架构特性**:采用 Shared-Nothing 架构,每个 Segment 存储**部分数据**和**本地元数据**。 --- ### **2. 一致性规则** #### **2.1 必须一致的内容** 所有 Segment 上 **全局元数据** 必须严格一致: - **表结构定义**:列定义(`pg_attribute`)、约束(`pg_constraint`)等。 - **对象标识符**:`oid`、`relfilenode`(全局唯一)。 - **分布策略**:分布键(`gp_distribution_policy`)和分区规则。 #### **2.2 允许差异的内容** 本地化统计信息可能不同: - **数据分布统计**:`reltuples`(行数)、`relpages`(数据页数)反映各 Segment 本地数据量。 - **存储细节**:`reltoastrelid`(TOAST 表 OID)可能不同(若使用随机分布策略)。 --- ### **3. 典型不一致场景** | **场景** | **是否正常** | **风险** | |-------------------------|--------------|------------------------------| | 表结构定义不同 | 异常 | 查询报错、数据损坏 | | 相同表名但不同 OID | 异常 | 对象引用失效 | | reltuples 值差异 | 正常 | 优化可能生成非最优执行计划 | | 部分 Segment 缺失表条目 | 异常 | 查询返回部分数据 | --- ### **4. 一致性检查方法** #### **4.1 使用 `gpcheckcat` 工具** ```bash # 检查系统目录一致性(包括 pg_class) gpcheckcat -p 5432 mydatabase ``` - 重点检查 `missing_rels`, `oid_duplicates` 等错误类型。 #### **4.2 手动验证示例** ```sql -- 检查表 oid 一致性(所有 Segment 应返回相同结果) SELECT gp_segment_id, oid, relname FROM gp_dist_random('pg_class') WHERE relname = 'my_table'; ``` --- ### **5. 修复不一致的操作** 1. **紧急处理** ```bash # 停止集群写入 gpstop -u ``` 2. **使用修复工具** ```bash # 自动修复(需确认备份) gpcheckcat --repair mydatabase ``` 3. **重建统计信息** ```sql ANALYZE my_table; -- 更新 reltuples/relpages ``` --- ### **6. 设计约束** - **临时表**:本地临时表 (`CREATE TEMP TABLE`) 仅在当前会话的 Segment 存在,属于正常差异。 - **随机分布表**:`reltoastrelid` 可能不同,但关联的 TOAST 表应通过 `gp_dist_random('pg_class')` 可见。 --- ### **7. 最佳实践** - 定期运行 `gpcheckcat` 进行健康检查 - 重要 DDL 操作后执行 `ANALYZE` - 使用 `gpexpand` 扩容时严格遵循操作流程 - 避免手动修改系统表(如 `UPDATE pg_class SET ...`) --- 若发现 **表结构定义不一致** 等关键问题,需立即停止业务并联系 Greenplum 技术支持。对于统计信息差异,可通过 `ANALYZE` 或 `VACUUM ANALYZE` 刷新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值