Skip to content

[refactor](fe) Refactor SummaryProfile to use QueryTrace/ProfileSpan dynamic tracing#61603

Open
morningman wants to merge 5 commits intoapache:masterfrom
morningman:refactor/summary-profile-trace
Open

[refactor](fe) Refactor SummaryProfile to use QueryTrace/ProfileSpan dynamic tracing#61603
morningman wants to merge 5 commits intoapache:masterfrom
morningman:refactor/summary-profile-trace

Conversation

@morningman
Copy link
Contributor

Proposed changes

What problem does this PR solve?

Issue Number: close #xxx

Problem Summary:

The current SummaryProfile implementation in Doris FE has several issues:

  • Hard-coded metric keys: All timing metrics are defined as static final Strings with corresponding timestamp fields, making it difficult to add new metrics.
  • Fragile timestamp pairs: Durations are computed from start/finish timestamp pairs (e.g., nereidsAnalysisFinishTime - nereidsLockTableFinishTime), where incorrect ordering of setter calls leads to negative durations.
  • Non-composable: Timing logic is scattered across NereidsPlanner, StmtExecutor, ConnectProcessor, FileQueryScanNode, HMSTransaction, etc., all directly calling SummaryProfile setters.

This PR introduces a new QueryTrace/ProfileSpan system that replaces the legacy approach:

  • ProfileSpan implements AutoCloseable for safe, scoped timing via try-with-resources.
  • QueryTrace provides dynamic metric registration via startSpan(), recordDuration(), addCounter(), and setText().
  • A ThreadLocal span stack enables automatic parent-child relationship detection.
  • Metrics are registered on-the-fly, eliminating the need for pre-declared fields.

Changes

Phase 1 - Core Infrastructure + NereidsPlanner (c1121e3)

  • New classes: ProfileSpan, QueryTrace
  • Enhanced RuntimeProfile to support indented addInfoString
  • Migrated all NereidsPlanner timing to ProfileSpan/QueryTrace
  • Migrated MV rewrite, partition pruning, fold-constant, and TVF init timing

Phase 2 - Data Source + Getter Bridge (00939aa)

  • Migrated FileQueryScanNode, HiveScanNode, HiveTableSink timing
  • Added getTraceDurationMs() bridge in SummaryProfile getters

Phase 3 - StmtExecutor + HMSTransaction (6ea75e4)

  • Migrated StmtExecutor outer container timings (plan, parse, schedule, fetch, write)
  • Migrated ConnectProcessor parse timing
  • Replaced Optional<SummaryProfile> with Optional<QueryTrace> in HMSTransaction
  • Migrated all HMS filesystem/partition timing and counters

Phase 4 - Cleanup (bc0af91, d92c6ab)

  • Removed ~280 lines of dead setter methods and backing fields
  • Removed dead legacy fallback block in updateExecutionSummaryProfile()
  • Simplified getters to QueryTrace-only (no fallback)
  • Rewrote SummaryProfileTest to use QueryTrace API
  • Fixed all checkstyle issues (import order, indentation, unused imports)

Release note

None

Check List (For Author)

  • Test: Unit Test (SummaryProfileTest rewritten for QueryTrace API)
  • Behavior changed: No (profile output format is preserved)
  • Does this need documentation: No

### What problem does this PR solve?

Issue Number: close #xxx

Problem Summary:
SummaryProfile uses hardcoded timestamp fields and manual setXxxTime() calls
scattered across the codebase. This makes adding new metrics error-prone, requires
synchronized blocks for each accumulator, tightly couples consumers (NereidsPlanner,
PartitionPruner, etc.) to SummaryProfile internals, and obscures parent-child
relationships between timing phases.

### Release note

None

### Check List (For Author)

- Test: No need to test (pure refactoring, runtime behavior unchanged; legacy
  fields preserved for backward compatibility during migration)
- Behavior changed: No
- Does this need documentation: No

---

Introduces two new classes:

- **ProfileSpan** (AutoCloseable): A timed span that automatically records
  duration and manages the ThreadLocal span stack. Includes NO_OP sentinel
  for null-safe usage in UT contexts.

- **QueryTrace**: Per-query tracing container with three metric types (Span,
  Counter, Text). Uses ThreadLocal span stack for automatic parent detection,
  LinkedHashMap for insertion-order display, and ReentrantReadWriteLock for
  thread safety. Supports both try-with-resources spans and pre-computed
  recordDuration() for metrics like GC time.

Migrated callers:
- NereidsPlanner: collectAndLockTable, analyze, rewrite, preMaterializedViewRewrite,
  optimize, splitFragments (translate), doDistribute, GC time
- AbstractMaterializedViewRule: MV rewrite time, collect table partition time
- PartitionPruner: partition prune time
- FoldConstantRuleOnBE: BE fold constant time
- ExternalFileTableValuedFunction: TVF init time

Supporting changes:
- RuntimeProfile: self-contained indentation via addInfoString(key, value, indent)
- SummaryProfile: QueryTrace field + populateProfile() integration
- StatementContext: getQueryTrace() convenience accessor
…dge getters

### What problem does this PR solve?

Issue Number: close #xxx

Problem Summary:
Phase 3 of SummaryProfile refactoring: migrate external data source profiling
(FileQueryScanNode, HiveScanNode, HiveTableSink) to use QueryTrace.recordDuration
instead of setting legacy timestamp pairs on SummaryProfile. Also bridge existing
SummaryProfile getter methods (used by MetricRepo histograms and plan debug output)
to read from QueryTrace first, falling back to legacy timestamp fields. This ensures
no regression in monitoring metrics while the migration progresses.

### Release note

None

### Check List (For Author)

- Test: No need to test (pure refactoring, backward compatible via fallback getters)
- Behavior changed: No
- Does this need documentation: No

---

Changes:

SummaryProfile:
- Add getTraceDurationMs() bridge helper
- Update all Nereids getXxxTimeMs() to read QueryTrace first
- Update getPrettyNereidsXxx() to delegate to getXxxTimeMs()
- Update getInitScanNodeTimeMs/getFinalizeScanNodeTimeMs/getCreateScanRangeTimeMs
- Remove duplicate Nereids entries from updateExecutionSummaryProfile
- Fix addNereidsPartitiionPruneTime (was incorrectly mutating externalTvfInitTime)

FileQueryScanNode:
- Replace setInitScanNodeStartTime/FinishTime with recordDuration
- Replace setFinalizeScanNodeStartTime/FinishTime with recordDuration
- Replace setGetSplitsStartTime/FinishTime with recordDuration
- Replace setCreateScanRangeFinishTime with recordDuration
- Add recordDurationToTrace helper

HiveScanNode:
- Replace setGetPartitionsFinishTime with QueryTrace recordDuration
- Replace setGetPartitionFilesFinishTime with QueryTrace recordDuration

HiveTableSink:
- Replace setSinkGetPartitionsStartTime/FinishTime with QueryTrace recordDuration
### What problem does this PR solve?

Issue Number: close #xxx

Problem Summary:
Phase 3 of SummaryProfile refactoring: migrate the outer container timings
(StmtExecutor, ConnectProcessor, AbstractInsertExecutor) and HMSTransaction
filesystem/HMS profiling to use QueryTrace. This eliminates the shared
tempStarTime/freshXxx pattern in HMSTransaction and records all durations
directly via QueryTrace.recordDuration(). SummaryProfile.updateExecutionSummaryProfile
is restructured: migrated metrics are only emitted via populateProfile() when
QueryTrace is available, falling back to legacy timeline output when null.

### Release note

None

### Check List (For Author)

- Test: No need to test (pure refactoring, backward compatible via fallback)
- Behavior changed: No
- Does this need documentation: No

---

Changes:

StmtExecutor:
- Record Plan Time, Parse SQL Time, Schedule Time, Fetch/Write Result Time
  durations in QueryTrace alongside legacy timestamp setters
- Record Executed By Frontend text via QueryTrace.setText
- Record Query Begin Time via QueryTrace.setText

ConnectProcessor:
- Record Parse SQL Time duration in QueryTrace after setting legacy timestamps

AbstractInsertExecutor:
- Record Schedule Time and Fetch Result Time in QueryTrace

HMSTransaction:
- Replace Optional<SummaryProfile> with Optional<QueryTrace>
- Migrate waitForAsyncFileSystemTasks, doAddPartitionsTask,
  doUpdateStatisticsTasks, wrapperRename/Delete methods
- Use QueryTrace.recordDuration and addCounter instead of tempStarTime

SummaryProfile:
- Restructure updateExecutionSummaryProfile: migrated metrics only emit
  legacy entries when queryTrace is null
- Bridge getPlanTimeMs and getScheduleTimeMs through getTraceDurationMs
…ryProfile

### What problem does this PR solve?

Issue Number: close #xxx

Problem Summary:
Phase 4 cleanup of SummaryProfile refactoring. Removes ~250 lines of dead code:
all Nereids timing setters (setNereidsAnalysisTime, setNereidsRewriteTime, etc.),
data source scan node setters (setInitScanNodeStartTime, setGetSplitsStartTime,
etc.), HMS/filesystem setters (freshFilesystemOptTime, setHmsAddPartitionTime,
addRenameFileCnt, etc.), and their backing fields. These were fully superseded
by QueryTrace in Phases 1-3. Getters now read exclusively from QueryTrace with
no legacy fallback for cleaned-up metrics. The HMS transaction summary block
in setTransactionSummary is removed as those metrics are now emitted by
QueryTrace.populateProfile(). Also migrates InitMaterializationContextHook
from setNereidsCollectTablePartitionFinishTime to QueryTrace, and rewrites
SummaryProfileTest to exercise the new QueryTrace API.

### Release note

None

### Check List (For Author)

- Test: Unit Test (SummaryProfileTest rewritten)
- Behavior changed: No
- Does this need documentation: No

---

Removed methods:
- setNereidsLockTableFinishTime, setNereidsAnalysisTime, setNereidsRewriteTime
- setNereidsOptimizeTime, setNereidsTranslateTime, setNereidsDistributeTime
- setNereidsGarbageCollectionTime, sumBeFoldTime
- setNereidsPreRewriteByMvFinishTime, setNereidsCollectTablePartitionFinishTime
- addCollectTablePartitionTime
- setInitScanNodeStartTime/FinishTime, setFinalizeScanNodeStartTime/FinishTime
- setGetSplitsStartTime/FinishTime, setGetPartitionsFinishTime
- setGetPartitionFilesFinishTime, setSinkGetPartitionsStartTime/FinishTime
- setCreateScanRangeFinishTime
- freshFilesystemOptTime, setHmsAddPartitionTime, addHmsAddPartitionCnt
- setHmsUpdatePartitionTime, addHmsUpdatePartitionCnt
- addRenameFileCnt, incRenameDirCnt, incDeleteDirRecursiveCnt, incDeleteFileCnt
- addNereidsMvRewriteTime, addExternalCatalogMetaTime, addExternalTvfInitTime
- addNereidsPartitiionPruneTime

Removed fields:
- nereidsLockTableFinishTime, nereidsAnalysisFinishTime, nereidsRewriteFinishTime
- nereidsOptimizeFinishTime, nereidsTranslateFinishTime, nereidsDistributeFinishTime
- nereidsCollectTablePartitionFinishTime, nereidsCollectTablePartitionTime
- nereidsPreRewriteByMvFinishTime, nereidsGarbageCollectionTime, nereidsBeFoldConstTime
- initScanNodeStartTime/FinishTime, finalizeScanNodeStartTime/FinishTime
- getSplitsStartTime/FinishTime, getPartitionsFinishTime, getPartitionFilesFinishTime
- sinkSetPartitionValuesStartTime/FinishTime, createScanRangeFinishTime
- filesystemOptTime, hmsAddPartitionTime/Cnt, hmsUpdatePartitionTime/Cnt
- filesystemRenameFileCnt/RenameDirCnt/DeleteDirCnt/DeleteFileCnt
- nereidsMvRewriteTime, externalCatalogMetaTime, externalTvfInitTime
- nereidsPartitiionPruneTime
### What problem does this PR solve?

Problem Summary:
The updateExecutionSummaryProfile() method had a dead code block guarded by
`if (queryTrace == null)` that still referenced deleted scan-node timestamp
fields (initScanNodeFinishTime, getSplitsStartTime, etc.). Since queryTrace
is always initialized as `new QueryTrace()` (never null), this block was
unreachable dead code. Removing it fixes the compilation errors.

### Release note

None

### Check List (For Author)

- Test: No need to test (removes dead code that caused compilation failure)
- Behavior changed: No
- Does this need documentation: No
@hello-stephen
Copy link
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@morningman
Copy link
Contributor Author

run buildall

@doris-robot
Copy link

TPC-H: Total hot run time: 26723 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit d92c6abaf311de05313ad394bd95a8d6b1871490, data reload: false

------ Round 1 ----------------------------------
orders	Doris	NULL	NULL	0	0	0	NULL	0	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	17610	4392	4272	4272
q2	q3	10648	763	516	516
q4	4680	376	257	257
q5	7539	1206	1039	1039
q6	189	173	149	149
q7	793	860	669	669
q8	9344	1490	1324	1324
q9	4975	4710	4658	4658
q10	6327	1906	1628	1628
q11	468	269	253	253
q12	749	599	465	465
q13	18027	2961	2177	2177
q14	223	233	218	218
q15	q16	738	750	671	671
q17	737	853	438	438
q18	5881	5356	5241	5241
q19	1253	986	640	640
q20	539	497	378	378
q21	4518	1869	1435	1435
q22	574	389	295	295
Total cold run time: 95812 ms
Total hot run time: 26723 ms

----- Round 2, with runtime_filter_mode=off -----
orders	Doris	NULL	NULL	150000000	42	6422171781	NULL	22778155	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	4821	4718	4557	4557
q2	q3	3846	4341	3816	3816
q4	891	1237	825	825
q5	4102	4430	4369	4369
q6	198	181	139	139
q7	1767	1636	1517	1517
q8	2515	2764	2602	2602
q9	7476	7162	7382	7162
q10	3775	3995	3598	3598
q11	502	431	424	424
q12	495	599	455	455
q13	2716	3599	2391	2391
q14	291	303	290	290
q15	q16	750	821	717	717
q17	1231	1386	1394	1386
q18	7171	6891	6570	6570
q19	940	894	936	894
q20	2249	2251	1975	1975
q21	4008	3523	3366	3366
q22	438	433	391	391
Total cold run time: 50182 ms
Total hot run time: 47444 ms

@doris-robot
Copy link

TPC-DS: Total hot run time: 169103 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit d92c6abaf311de05313ad394bd95a8d6b1871490, data reload: false

query5	4323	640	487	487
query6	332	235	208	208
query7	4215	473	270	270
query8	354	250	236	236
query9	8748	2749	2738	2738
query10	531	400	354	354
query11	6999	5114	4894	4894
query12	186	129	125	125
query13	1276	461	353	353
query14	5754	3769	3552	3552
query14_1	2864	2862	2819	2819
query15	207	196	179	179
query16	975	474	453	453
query17	909	741	625	625
query18	2447	440	335	335
query19	208	207	175	175
query20	134	129	124	124
query21	212	132	106	106
query22	13318	14130	14830	14130
query23	16178	16132	15655	15655
query23_1	15761	15982	15687	15687
query24	7207	1616	1213	1213
query24_1	1234	1223	1245	1223
query25	546	468	427	427
query26	1236	267	193	193
query27	2729	480	290	290
query28	5070	1840	1817	1817
query29	875	571	504	504
query30	302	233	194	194
query31	1078	955	885	885
query32	82	73	73	73
query33	527	333	286	286
query34	1294	898	537	537
query35	650	695	609	609
query36	1167	1179	1024	1024
query37	143	98	86	86
query38	3041	2973	2917	2917
query39	880	848	820	820
query39_1	818	801	820	801
query40	235	156	136	136
query41	61	58	59	58
query42	267	260	261	260
query43	258	261	224	224
query44	
query45	203	190	184	184
query46	911	1004	628	628
query47	2112	2150	2070	2070
query48	303	320	219	219
query49	627	460	417	417
query50	692	279	210	210
query51	4081	4024	4016	4016
query52	262	263	268	263
query53	292	344	286	286
query54	306	270	277	270
query55	98	86	84	84
query56	317	325	317	317
query57	1952	1835	1567	1567
query58	283	276	276	276
query59	2789	2944	2744	2744
query60	349	341	329	329
query61	157	159	174	159
query62	631	591	539	539
query63	316	283	281	281
query64	5005	1273	999	999
query65	
query66	1491	456	355	355
query67	24226	24357	24225	24225
query68	
query69	403	317	278	278
query70	995	921	940	921
query71	341	322	303	303
query72	2981	2871	2641	2641
query73	556	551	323	323
query74	9613	9540	9444	9444
query75	2883	2789	2493	2493
query76	2300	1025	681	681
query77	381	398	320	320
query78	10938	11103	10443	10443
query79	1230	757	581	581
query80	1384	697	542	542
query81	552	257	229	229
query82	1019	152	119	119
query83	337	267	240	240
query84	297	122	98	98
query85	914	498	455	455
query86	416	329	299	299
query87	3187	3182	3034	3034
query88	3570	2661	2648	2648
query89	424	368	347	347
query90	2013	181	179	179
query91	170	165	140	140
query92	80	80	72	72
query93	994	856	507	507
query94	634	317	302	302
query95	596	402	324	324
query96	650	520	234	234
query97	2429	2485	2398	2398
query98	230	219	217	217
query99	1002	913	916	913
Total cold run time: 250744 ms
Total hot run time: 169103 ms

@hello-stephen
Copy link
Contributor

FE UT Coverage Report

Increment line coverage 60.86% (255/419) 🎉
Increment coverage report
Complete coverage report

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants