一、 stream线程池实现设计
Stream线程池中stream线程整体执行流程如下图所示:
Stream线程池中stream线程整体执行流程如下图所示:
图一、stream线程执行流程
其中,GUC参数的设置逻辑为图八所示:
父线程保存自己的guc_variables在syncGucVariables中,syncGucVariables是需要传递给stream的结构用以保证父子线程guc参数的一致。然后父线程在初始化streamProducer时将syncGucVariables保存在该结构中传递。
Stream线程根据streamProducer初始化自己的syncGucVariables变量,首先reset所有的guc变量,然后根据syncGucVariables修正自己的variables。
图二、GUC参数修改
执行计划时,stream线程需要可视父线程的事务信息,因此在ExecuteStreamPlan中,stream线程池前后事务的继承和提交逻辑为:
图三、事务的继承和提交逻辑
二、测试场景
【场景一】集群基础行为场景——建立多数据库场景
- Create database ***;(建立多库)
- 分别执行带stream算子的查询;
例:create table test_01(c1 int, c2 int)with(orientation=column) distribute by hash(c1);
insert into test_01 select generate_series(1,100), generate_series(1,100);analyze test_01;
select * from test_01 a, test_01 b, test_01 c, test_01 d, test_01 e, test_01 f where a.c2 =b.c2 and c.c2 = d.c2 and e.c2=f.c2 limit 100;
- 查询结束,查pgxc_thread_wait_status看DN节点:预期stream线程状态为wait thread cond。且多database之间stream线程不复用。
【场景二】集群基础行为场景——建立多用户场景
- Create user ***;(建立多用户)
- 分别执行带stream算子的查询;(参考场景一示例)
- 查询结束,查pgxc_thread_wait_status看DN节点:预期stream线程状态为wait thread cond。且多user之间stream线程可以复用。
例:用户一执行完查询,视图中显示共有四个stream线程在线程池,用户二执行同样查询返回正确结果,视图中的stream线程个数不变,且线程号也是一致的,则说明复用。
【场景三】集群基础行为场景——线程清理场景
- 调整guc参数max_stream_pool的值,观测是否生效;预期:当设置max_stream_pool小于当前idle线程个数,支持线程个数实时减少;当设置max_stream_pool大于当前idle线程个数,将由业务驱动线程个数的增加,但是不会超过max_stream_pool。
- 执行clean connection(ALL force),查看stream线程是否被清理;预期:该database的stream线程被完全清理。
- 执行drop database命令,查看stream线程是否被清理;预期:该database的stream线程被完全清理。
【场景4】集群基础行为场景——stream线程池性能测试
- 分别测试50、100、300、500、1000并发下,每并发100查询的QPS,对比stream线程池性能变化。
- 单语句stream多,并发小;单语句stream少,并发大两种场景。
1.1.2 扩展场景
【场景一】集群故障场景
- Kill dn 节点,节点被重新拉起,继续并发执行查询;
- 集群规模性重启,并发执行查询;
- 故障场景测试用例下,并发执行带stream算子的查询。
预期:结合pgxc_thread_wait_status视图,并发查询能否继续执行,是否正常报错,无core无hang。
【场景二】集群特殊业务场景
- 模拟高并发查询,观察stream线程情况;
- 震荡模型下,观察stream线程大规模快速建立、清理的场景是否正常运行;
- 多用户共享一个database,多用户共享多个database,观察stream线程复用情况。
预期:stream线程池正常发挥作用,不同database线程不复用,复用与user无关。