Greenplum数据库统计信息——分布式采样

2023-03-28 00:00:00 函数 执行 节点 采样 流程


当在Postgresql数据库中执行Analyze时,会经过如下流程:准备工作流程(1. 创建anl_context内存上下文,并切换到该内存上下文中 2. 切换到表所有者的userid,以便任何索引函数都作为该用户运行 3. 需要进一步确定要分析一个表中的哪些列:用户可能指定只分析表中的某几个列,被频繁访问的列才更有被分析的价值,然后还要打开待分析表的所有索引,看看是否有可以被分析的。)、列采样工作流程(1. 使用所有可分析列中的坏情况,确定需要采样的行数 2. 使用采样函数获取采样行 3. 计算统计数据)、analyze统计信息收集(1. 主要分为两个部分:一个统计信息系统表pg_statistic和pg_class的更新 2. 向PgStat进程发送统计信息)。其中除了列采样工作流程中的使用采样函数获取采样行之外的流程都是标准流程,和表数据是不相关的。对于greeplum来说统计信息是存储在Master节点pg_statistic等系统表中,而数据是存储在Segment节点上,因此Greenplum数据库Master节点执行的Analyze流程需要从Segment节点数据表中获取表采样行,acquire_sample_rows和acquire_inherited_sample_rows函数需要从单机版本变成分布式版本采样函数,对应的在Segment上也有对应的T_GpAcquireSampleRowsStmt节点调用analyze_rel函数进行数据的采样工作。


分布式采样


从上述代码对比可知,Greenplum的采样函数对Master节点QD角色添加了分支,走acquire_sample_rows_dispatcher函数,而Segment节点QE角色走原来Postgres的采样函数采样流程。acquire_sample_rows_dispatcher函数执行流程如下所示:

1.先根据表分布计算每个segment的target rows perseg_tagrows
2.创建GpAcquireSampleRowsStmt节点,设置stmt->relOid为形参onerel,设置stmt->va_cols为形参val_cols,设置targrows为perseg_targrows,inherited为形参inh,执行CdbDispatchUtilityStatement((Node *)stmt, DF_WITH_SNAPSHOT, NIL, &cdb_pgresults)
3.创建tuple_descriptor,并初始化Entry
4.从第二步执行返回中提取数据
从上面第3步可知,QD通过acquire_sample_rows_dispatcher函数向Segment QE下发了UtilityStatement GpAcquireSampleRowsStmt节点,以通知QE对相关表数据行进行采样。

GpAcquireSampleRowsStmt节点
ExecGpAcquireSampleRowsStmt用于处理T_GpAcquireSampleRowsStmt节点,其主要工作就是创建gp_acquire_sample_rows_context ctx,设置从QD下发的targrows需采样的行数、inherited是否是父表到其对应成员中,然后初始化VacuumParams结构体,使用这些信息执行analyze_rel函数进入Analyze相同的流程,当然这时ctx不为null,因为已经创建且初始化过成员了,具体流程如下所示。



本文来源:https://blog.csdn.net/asmartkiller/article/details/127331804

相关文章