已合并
修复存储过程中执行完单条SQL后没有释放smp相关资源的问题 #7757
totaj创建于 2025年5月22日
修复存储过程中执行完单条SQL后没有释放smp相关资源的问题 #7757
已合并
共 7 个文件变更+178-12
| @@ -3920,6 +3920,9 @@ static int exec_stmt_block(PLpgSQL_execstate* estate, PLpgSQL_stmt_block* block, | |||
| 3920 | 3920 | ||
| 3921 | exec_exception_cleanup(estate, &excptContext); | 3921 | exec_exception_cleanup(estate, &excptContext); |
| 3922 | 3922 | ||
| 3923 | + if (!StreamThreadAmI()) { | ||
| 3924 | + StreamNodeGroup::ReleaseStreamGroup(false); | ||
| 3925 | + } | ||
| 3923 | AutoDopControl dopControl; | 3926 | AutoDopControl dopControl; |
| 3924 | dopControl.CloseSmp(); | 3927 | dopControl.CloseSmp(); |
| 3925 | 3928 | ||
| @@ -362,6 +362,7 @@ StreamNodeGroup::StreamNodeGroup() | |||
| 362 | 362 | ||
| 363 | m_portal = NULL; | 363 | m_portal = NULL; |
| 364 | 364 | ||
| 365 | + m_spiLevel = u_sess->SPI_cxt._connected; | ||
| 365 | } | 366 | } |
| 366 | 367 | ||
| 367 | StreamNodeGroup::~StreamNodeGroup() | 368 | StreamNodeGroup::~StreamNodeGroup() |
| @@ -1075,18 +1076,21 @@ void StreamNodeGroup::syncQuit(StreamObjStatus status) | |||
| 1075 | 1076 | ||
| 1076 | void StreamNodeGroup::ReleaseStreamGroup(bool resetSession, StreamObjStatus status) | 1077 | void StreamNodeGroup::ReleaseStreamGroup(bool resetSession, StreamObjStatus status) |
| 1077 | { | 1078 | { |
| 1078 | - if (u_sess->stream_cxt.global_obj != NULL) { | 1079 | + /* we can only release inner StreamNodeGroup */ |
| 1079 | - StreamTopConsumerIam(); | 1080 | + if (u_sess->stream_cxt.global_obj == NULL || |
| 1080 | - /* Set sync point for waiting all stream threads complete. */ | 1081 | + u_sess->stream_cxt.global_obj->m_spiLevel < u_sess->SPI_cxt._connected) { |
| 1081 | - StreamNodeGroup::syncQuit(status); | 1082 | + return; |
| 1082 | - UnRegisterStreamSnapshots(); | ||
| 1083 | - StreamNodeGroup::destroy(status); | ||
| 1084 | - if (!resetSession) { | ||
| 1085 | - /* reset some flag related to stream */ | ||
| 1086 | - ResetStreamEnv(); | ||
| 1087 | - } | ||
| 1088 | } | 1083 | } |
| 1089 | - if (resetSession) { | 1084 | + |
| 1085 | + StreamTopConsumerIam(); | ||
| 1086 | + /* Set sync point for waiting all stream threads complete. */ | ||
| 1087 | + StreamNodeGroup::syncQuit(status); | ||
| 1088 | + UnRegisterStreamSnapshots(); | ||
| 1089 | + StreamNodeGroup::destroy(status); | ||
| 1090 | + if (!resetSession) { | ||
| 1091 | + /* reset some flag related to stream */ | ||
| 1092 | + ResetStreamEnv(); | ||
| 1093 | + } else { | ||
| 1090 | ResetSessionEnv(); | 1094 | ResetSessionEnv(); |
| 1091 | } | 1095 | } |
| 1092 | } | 1096 | } |
| @@ -3542,6 +3542,12 @@ int _SPI_end_call(bool use_exec) | |||
| 3542 | */ | 3542 | */ |
| 3543 | u_sess->SPI_cxt._curid--; | 3543 | u_sess->SPI_cxt._curid--; |
| 3544 | 3544 | ||
| 3545 | + | ||
| 3546 | + if (!StreamThreadAmI()) { | ||
| 3547 | + StreamNodeGroup::ReleaseStreamGroup(false); | ||
| 3548 | + } | ||
| 3549 | + | ||
| 3550 | + | ||
| 3545 | /* must put last after smp thread has reach the sync point, then we can release the memory. */ | 3551 | /* must put last after smp thread has reach the sync point, then we can release the memory. */ |
| 3546 | if (use_exec) { | 3552 | if (use_exec) { |
| 3547 | /* switch to the procedure memory context */ | 3553 | /* switch to the procedure memory context */ |
| @@ -535,6 +535,8 @@ private: | |||
| 535 | StreamObjStatus m_quitStatus; | 535 | StreamObjStatus m_quitStatus; |
| 536 | 536 | ||
| 537 | static HTAB* m_streamDescHashTbl; | 537 | static HTAB* m_streamDescHashTbl; |
| 538 | + | ||
| 539 | + int m_spiLevel; | ||
| 538 | }; | 540 | }; |
| 539 | 541 | ||
| 540 | extern bool IsThreadProcessStreamRecursive(); | 542 | extern bool IsThreadProcessStreamRecursive(); |
| @@ -0,0 +1,28 @@ | |||
| 1 | +create schema test_smp2; | ||
| 2 | +set search_path=test_smp2; | ||
| 3 | + | ||
| 4 | +create table t1(a int, b int); | ||
| 5 | +--test smp is work good | ||
| 6 | +explain (costs off) select /*+ set(query_dop 1004) */ a,sum(b) from t1 group by a; | ||
| 7 | + | ||
| 8 | +create or replace procedure test_pro() as | ||
| 9 | +begin | ||
| 10 | +create table test_smp2.pro_t1 as select /*+ set(query_dop 1004) */ a,sum(b) from t1 group by a; | ||
| 11 | +create table test_smp2.pro_t2 as select /*+ set(query_dop 1004) */ a,sum(b) from t1 group by a; | ||
| 12 | +end; | ||
| 13 | +/ | ||
| 14 | + | ||
| 15 | +--let procedure print plan | ||
| 16 | +set enable_auto_explain=on; | ||
| 17 | +set auto_explain_level=notice; | ||
| 18 | + | ||
| 19 | +select test_pro(); | ||
| 20 | + | ||
| 21 | +--clean up | ||
| 22 | +reset enable_auto_explain; | ||
| 23 | +reset auto_explain_level; | ||
| 24 | +drop table pro_t1; | ||
| 25 | +drop table pro_t2; | ||
| 26 | +drop table t1; | ||
| 27 | +drop procedure test_pro; | ||
| 28 | +drop schema test_smp2 cascade; | ||
| @@ -0,0 +1,123 @@ | |||
| 1 | +create schema test_smp2; | ||
| 2 | +set search_path=test_smp2; | ||
| 3 | +create table t1(a int, b int); | ||
| 4 | +--test smp is work good | ||
| 5 | +explain (costs off) select /*+ set(query_dop 1004) */ a,sum(b) from t1 group by a; | ||
| 6 | + QUERY PLAN | ||
| 7 | +---------------------------------------------------------- | ||
| 8 | + Streaming(type: LOCAL GATHER dop: 1/4) | ||
| 9 | + -> HashAggregate | ||
| 10 | + Group By Key: a | ||
| 11 | + -> Streaming(type: LOCAL REDISTRIBUTE dop: 4/4) | ||
| 12 | + -> HashAggregate | ||
| 13 | + Group By Key: a | ||
| 14 | + -> Seq Scan on t1 | ||
| 15 | +(7 rows) | ||
| 16 | + | ||
| 17 | +create or replace procedure test_pro() as | ||
| 18 | +begin | ||
| 19 | +create table test_smp2.pro_t1 as select /*+ set(query_dop 1004) */ a,sum(b) from t1 group by a; | ||
| 20 | +create table test_smp2.pro_t2 as select /*+ set(query_dop 1004) */ a,sum(b) from t1 group by a; | ||
| 21 | +end; | ||
| 22 | +/ | ||
| 23 | +--let procedure print plan | ||
| 24 | +set enable_auto_explain=on; | ||
| 25 | +set auto_explain_level=notice; | ||
| 26 | +select test_pro(); | ||
| 27 | +NOTICE: | ||
| 28 | +QueryPlan | ||
| 29 | + | ||
| 30 | +----------------------------NestLevel:0---------------------------- | ||
| 31 | +Query Text: select test_pro(); | ||
| 32 | +Name: datanode1 | ||
| 33 | +--?.* | ||
| 34 | + Output: test_pro() | ||
| 35 | + | ||
| 36 | + | ||
| 37 | +NOTICE: | ||
| 38 | +QueryPlan | ||
| 39 | + | ||
| 40 | +----------------------------NestLevel:1---------------------------- | ||
| 41 | +Query Text: create table test_smp2.pro_t1 as select /*+ set(query_dop 1004) */ a,sum(b) from t1 group by a | ||
| 42 | +Name: datanode1 | ||
| 43 | +--?.* | ||
| 44 | + Spawn on: All datanodes | ||
| 45 | + Consumer Nodes: All datanodes | ||
| 46 | +--?.* | ||
| 47 | +--?.* | ||
| 48 | + Output: t1.a, pg_catalog.sum((sum(t1.b))) | ||
| 49 | + Group By Key: t1.a | ||
| 50 | +--?.* | ||
| 51 | + Output: t1.a, (sum(t1.b)) | ||
| 52 | + Distribute Key: t1.a | ||
| 53 | + Spawn on: All datanodes | ||
| 54 | + Consumer Nodes: All datanodes | ||
| 55 | +--?.* | ||
| 56 | + Output: t1.a, sum(t1.b) | ||
| 57 | + Group By Key: t1.a | ||
| 58 | +--?.* | ||
| 59 | + Output: t1.a, t1.b | ||
| 60 | + | ||
| 61 | + | ||
| 62 | +CONTEXT: SQL statement "create table test_smp2.pro_t1 as select /*+ set(query_dop 1004) */ a,sum(b) from t1 group by a" | ||
| 63 | +PL/pgSQL function test_pro() line 2 at SQL statement | ||
| 64 | +referenced column: test_pro | ||
| 65 | +NOTICE: | ||
| 66 | +----------------------------NestLevel:1---------------------------- | ||
| 67 | +--?.* | ||
| 68 | + | ||
| 69 | +CONTEXT: SQL statement "create table test_smp2.pro_t1 as select /*+ set(query_dop 1004) */ a,sum(b) from t1 group by a" | ||
| 70 | +PL/pgSQL function test_pro() line 2 at SQL statement | ||
| 71 | +referenced column: test_pro | ||
| 72 | +NOTICE: | ||
| 73 | +QueryPlan | ||
| 74 | + | ||
| 75 | +----------------------------NestLevel:1---------------------------- | ||
| 76 | +Query Text: create table test_smp2.pro_t2 as select /*+ set(query_dop 1004) */ a,sum(b) from t1 group by a | ||
| 77 | +Name: datanode1 | ||
| 78 | +--?.* | ||
| 79 | + Spawn on: All datanodes | ||
| 80 | + Consumer Nodes: All datanodes | ||
| 81 | +--?.* | ||
| 82 | +--?.* | ||
| 83 | + Output: t1.a, pg_catalog.sum((sum(t1.b))) | ||
| 84 | + Group By Key: t1.a | ||
| 85 | +--?.* | ||
| 86 | + Output: t1.a, (sum(t1.b)) | ||
| 87 | + Distribute Key: t1.a | ||
| 88 | + Spawn on: All datanodes | ||
| 89 | + Consumer Nodes: All datanodes | ||
| 90 | +--?.* | ||
| 91 | + Output: t1.a, sum(t1.b) | ||
| 92 | + Group By Key: t1.a | ||
| 93 | +--?.* | ||
| 94 | + Output: t1.a, t1.b | ||
| 95 | + | ||
| 96 | + | ||
| 97 | +CONTEXT: SQL statement "create table test_smp2.pro_t2 as select /*+ set(query_dop 1004) */ a,sum(b) from t1 group by a" | ||
| 98 | +PL/pgSQL function test_pro() line 3 at SQL statement | ||
| 99 | +referenced column: test_pro | ||
| 100 | +NOTICE: | ||
| 101 | +----------------------------NestLevel:1---------------------------- | ||
| 102 | +--?.* | ||
| 103 | + | ||
| 104 | +CONTEXT: SQL statement "create table test_smp2.pro_t2 as select /*+ set(query_dop 1004) */ a,sum(b) from t1 group by a" | ||
| 105 | +PL/pgSQL function test_pro() line 3 at SQL statement | ||
| 106 | +referenced column: test_pro | ||
| 107 | +NOTICE: | ||
| 108 | +----------------------------NestLevel:0---------------------------- | ||
| 109 | +--?.* | ||
| 110 | + | ||
| 111 | + test_pro | ||
| 112 | +---------- | ||
| 113 | + | ||
| 114 | +(1 row) | ||
| 115 | + | ||
| 116 | +--clean up | ||
| 117 | +reset enable_auto_explain; | ||
| 118 | +reset auto_explain_level; | ||
| 119 | +drop table pro_t1; | ||
| 120 | +drop table pro_t2; | ||
| 121 | +drop table t1; | ||
| 122 | +drop procedure test_pro; | ||
| 123 | +drop schema test_smp2 cascade; | ||
| @@ -18,7 +18,7 @@ test: hw_audit_system_func | |||
| 18 | 18 | ||
| 19 | test: performance_enhance | 19 | test: performance_enhance |
| 20 | test: explain_fqs | 20 | test: explain_fqs |
| 21 | -test: explain_pbe | 21 | +test: explain_pbe smp_2 |
| 22 | 22 | ||
| 23 | # gs_basebackup | 23 | # gs_basebackup |
| 24 | # test: gs_basebackup | 24 | # test: gs_basebackup |