Skip to content

[opt](column) Reuse varbinary payload storage for derived columns#65217

Open
Mryange wants to merge 3 commits into
apache:masterfrom
Mryange:opt-column-varbinary-storage
Open

[opt](column) Reuse varbinary payload storage for derived columns#65217
Mryange wants to merge 3 commits into
apache:masterfrom
Mryange:opt-column-varbinary-storage

Conversation

@Mryange

@Mryange Mryange commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

ColumnVarbinary used to deep-copy non-inline payload bytes when building filtered or permuted result columns. Root cause: StringView only stores a lightweight pointer for non-inline values, while the previous column-local Arena ownership model could not keep source payload memory alive after a derived column reused those StringView entries.

This PR adds a generic AuxiliaryDataSet owner-retention helper and uses it in ColumnVarbinary. The column keeps an Arena* only as a typed, non-owning write handle; the actual Arena owner is retained by AuxiliaryDataSet. Derived filter and permute columns now copy StringView metadata and inherit the source owner set when non-inline values are present. clear() drops old owners and registers a fresh local Arena, so old payload memory can still be retained by existing derived columns without affecting new writes.

The change also adds unit coverage for AuxiliaryDataSet owner retention/de-duplication and for ColumnVarbinary derived columns remaining valid after the source column is cleared.

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No.
    • Yes.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

@hello-stephen

Copy link
Copy Markdown
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?

@Mryange

Mryange commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 78.95% (45/57) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 56.37% (23008/40817)
Line Coverage 40.03% (223782/558980)
Region Coverage 36.04% (177012/491130)
Branch Coverage 37.11% (78720/212111)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 92.98% (53/57) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 74.54% (29700/39842)
Line Coverage 58.60% (325680/555749)
Region Coverage 55.55% (273976/493197)
Branch Coverage 56.75% (120514/212348)

Comment thread be/src/core/column/column_varbinary.h Outdated
using Container = PaddedPODArray<doris::StringView>;

private:
struct Storage {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个东西直接用Arena就行了吧,还多套一层?感觉有点抽象啊

HappenLee
HappenLee previously approved these changes Jul 6, 2026

@HappenLee HappenLee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label Jul 6, 2026
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

PR approved by at least one committer and no changes requested.

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

PR approved by anyone and no changes requested.

@Mryange Mryange force-pushed the opt-column-varbinary-storage branch from 3bdef28 to 4efb4d2 Compare July 7, 2026 06:38
@Mryange

Mryange commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot removed the approved Indicates a PR has been approved by one committer. label Jul 7, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found one issue that should be fixed before merge: the new retained-owner path keeps source VARBINARY payload memory alive, but the column/block memory accounting no longer reports that retained memory.

Critical checkpoint conclusions:

  • Goal and tests: the PR targets avoiding deep copies while preserving filtered/permuted VARBINARY payload lifetime. The new tests cover readability after source clear, but not retained-memory accounting.
  • Scope: the code change is small and focused on ColumnVarbinary ownership plus unit coverage.
  • Concurrency: no new threads or shared mutable concurrent state were introduced.
  • Lifecycle: the main lifecycle change is source Arena retention through AuxiliaryDataSet; this is where the accepted accounting issue appears.
  • Config and compatibility: no new config, persistence, storage format, or FE/BE protocol compatibility concern found.
  • Parallel paths: filter and permute use the new shallow-copy retention path; insert/range/selector/direct varbinary writers still allocate or copy through the local column arena.
  • Tests and style: the new BE UT files are picked up by the recursive test glob. I did not run BE UTs because this review checkout lacks .worktree_initialized, thirdparty/installed, and thirdparty/installed/bin/protoc.
  • Observability, transactions, data writes: not applicable to this BE core column change.
  • Performance and memory: request changes for the under-reported retained memory described inline.

User focus: no additional user-provided review focus was supplied.

Subagent conclusions: optimizer-rewrite reported OPT-1 and tests-session-config reported TSC-001 for the same retained-memory accounting bug; I merged them as MAIN-001 and submitted it as the single inline comment. No candidate was dismissed except as a duplicate of MAIN-001. Convergence round 1 ended with both live subagents replying NO_NEW_VALUABLE_FINDINGS for this exact ledger/comment set.


size_t allocated_bytes() const override { return _data.allocated_bytes() + _arena.size(); }
size_t allocated_bytes() const override {
DCHECK(_arena != nullptr);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filter() and permute() can now make the result retain the source arena through _auxiliary_data, but this accounting still only includes the result column's fresh local _arena. After a filtered/permuted block keeps a large non-inline VARBINARY payload alive and the source is cleared or reused, Block::allocated_bytes() and Block::bytes() will sum these methods and under-report the retained payload memory. That bypasses the memory counters/backpressure paths that rely on block size. Please either keep copying non-inline payloads for derived columns, or make auxiliary owners contribute to byte_size()/allocated_bytes() without double-counting.

@Mryange

Mryange commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for one additional lifecycle/cleanup issue in ColumnVarbinary::clear().

I did not repeat the existing VARBINARY retained-memory accounting thread at discussion_r3534250446; that concern is already covered. The failed BE UT (macOS) check exits before compile at the environment gate because the runner reports JDK 25 while the job requires JDK 17, so I did not treat that as a patch-specific code issue.

Review coverage: inspected all five changed files, surrounding ColumnVarbinary, block filtering/clearing, COW, sort/permutation, join row-transfer, aggregation/hash consumer paths, BE unit-test registration, refreshed inline comments, and CI status. Static validation only: this checkout lacks .worktree_initialized, thirdparty/installed, and thirdparty/installed/bin/protoc; git diff --check is clean.

Subagent conclusions: optimizer-rewrite and tests-session-config both completed the required initial pass with NO_NEW_VALUABLE_FINDINGS, then both returned NO_NEW_VALUABLE_FINDINGS again in convergence round 1 for the final ledger/comment set containing MAIN-001. No subagent candidates were appended; the existing memory-accounting concern was marked duplicate-covered.

Critical checkpoint conclusions: the PR goal is clear and mostly focused, with unit coverage for owner retention after filter/permute. The remaining issue is a cleanup/lifecycle regression where clear() now allocates and is not exception-safe. No new concurrency, FE/BE protocol, persistence, config, or compatibility surface was introduced. Parallel block/filter/sort/join/aggregate paths were inspected for VARBINARY ownership behavior. Test files are picked up by the BE UT recursive glob, but local BE UTs could not be run in this runner due missing third-party dependencies.

void clear() override {
_data.clear();
_arena.clear();
reset_to_new_local_storage();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clear() is now on an allocation path because it calls reset_to_new_local_storage(), which clears the current owner set and then does std::make_shared<Arena>(). This method is reached from cleanup/reuse code such as MutableBlock::clear_column_data() noexcept (block.cpp:1286-1290), so an allocation failure while clearing a VARBINARY column can now terminate the process during cleanup; in non-noexcept callers it is also not exception-safe because _arena still points at the old Arena after _auxiliary_data.clear() destroys it if the new allocation throws. Please make the reset allocate the replacement owner before dropping the current one, and avoid introducing a throwing allocation into the clear/reuse path (for example by reusing the local Arena or by separating the local owner from borrowed owners).

@Mryange

Mryange commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review summary for head d32f82d.

I completed the review pass over all changed files:

  • be/src/core/auxiliary_data_set.h
  • be/src/core/block/block.cpp
  • be/src/core/block/block.h
  • be/src/core/column/column_varbinary.cpp
  • be/src/core/column/column_varbinary.h
  • be/test/core/auxiliary_data_set_test.cpp
  • be/test/core/column/column_varbinary_test.cpp

I did not add new inline comments in this pass. The substantiated issues I found are already covered by existing inline threads:

  • comment 3534250446 covers retained borrowed VARBINARY payload owners not being charged by allocated_bytes() / byte_size().
  • comment 3534421683 covers ColumnVarbinary::clear() adding a new allocation path on cleanup/reuse.

Critical checkpoint conclusions:

  • Goal and tests: the PR aims to keep non-inline ColumnVarbinary payloads alive after filter() / permute(). The new unit tests cover owner retention and filtered/permuted values surviving source clear. Test registration is covered by the existing recursive be/test/CMakeLists.txt core/*.cpp glob.
  • Scope: the patch is focused on VARBINARY owner retention and related tests, but it changes column memory/lifecycle behavior. The two existing inline comments remain the main correctness/backpressure concerns.
  • Concurrency and lifecycle: I found no new threaded state. Shared payload lifetime is represented by retained owners in AuxiliaryDataSet; the cleanup/reset allocation risk is already tracked by comment 3534421683.
  • Compatibility and persistence: no config, protocol, storage format, or EditLog compatibility changes were introduced.
  • Parallel paths: insert_from, insert_range_from, insert_indices_from, and replace_column_data still deep-copy non-inline payloads into the destination column; filter() and permute() are the intentional borrowed-owner paths.
  • Testing and CI: I did not run local BE tests because this checkout is missing .worktree_initialized, thirdparty/installed, and thirdparty/installed/bin/protoc. I checked the current BE UT (macOS) failure; it fails during environment setup with ERROR: The JAVA version is 25, it must be JDK-17., not in the added tests.
  • User focus: no additional user-provided review focus was supplied.

Subagent conclusions:

  • optimizer-rewrite: no new valuable findings; convergence round 1 returned NO_NEW_VALUABLE_FINDINGS.
  • tests-session-config: recorded duplicate-only notes for comments 3534250446 and 3534421683; convergence round 1 returned NO_NEW_VALUABLE_FINDINGS.

@Mryange

Mryange commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17591	4091	4090	4090
q2	2059	332	200	200
q3	10344	1530	842	842
q4	4716	473	342	342
q5	7807	853	555	555
q6	227	176	143	143
q7	787	851	621	621
q8	9972	1691	1658	1658
q9	6195	4368	4403	4368
q10	6812	1817	1520	1520
q11	501	353	317	317
q12	729	548	425	425
q13	18127	3459	2777	2777
q14	276	262	254	254
q15	q16	792	791	719	719
q17	1052	988	1060	988
q18	7281	5796	5552	5552
q19	1439	1300	1126	1126
q20	757	676	669	669
q21	5917	2737	2648	2648
q22	455	367	325	325
Total cold run time: 103836 ms
Total hot run time: 30139 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4912	4813	5089	4813
q2	302	374	240	240
q3	4951	5210	4762	4762
q4	2161	2190	1379	1379
q5	4925	4822	4758	4758
q6	234	184	130	130
q7	1965	1745	1545	1545
q8	2443	1962	1978	1962
q9	7315	7263	7357	7263
q10	4688	4658	4201	4201
q11	542	404	363	363
q12	740	762	533	533
q13	3002	3324	2804	2804
q14	282	284	252	252
q15	q16	685	695	614	614
q17	1291	1276	1273	1273
q18	7421	6913	6898	6898
q19	1157	1043	1084	1043
q20	2238	2220	1935	1935
q21	5268	4543	4402	4402
q22	507	449	448	448
Total cold run time: 57029 ms
Total hot run time: 51618 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 180194 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 d32f82d4fb8cb82c8f4ee020bba8de29dcf549ab, data reload: false

query5	4333	640	480	480
query6	476	225	206	206
query7	4869	600	342	342
query8	335	208	172	172
query9	8733	4038	4037	4037
query10	497	348	307	307
query11	5897	2364	2166	2166
query12	160	103	99	99
query13	1269	619	406	406
query14	6235	5317	4958	4958
query14_1	4321	4299	4292	4292
query15	215	206	181	181
query16	1007	471	451	451
query17	1106	709	563	563
query18	2461	465	335	335
query19	202	182	142	142
query20	110	110	106	106
query21	234	155	129	129
query22	13665	13623	13508	13508
query23	17229	16576	16194	16194
query23_1	16295	16271	16206	16206
query24	7614	1804	1300	1300
query24_1	1334	1315	1263	1263
query25	573	460	396	396
query26	1329	362	216	216
query27	2635	580	387	387
query28	4535	2012	1997	1997
query29	1100	647	513	513
query30	327	264	228	228
query31	1124	1110	983	983
query32	103	64	63	63
query33	524	337	260	260
query34	1184	1115	666	666
query35	794	786	680	680
query36	1397	1362	1210	1210
query37	153	113	96	96
query38	1888	1716	1643	1643
query39	931	916	898	898
query39_1	873	877	901	877
query40	250	167	140	140
query41	72	70	70	70
query42	101	98	95	95
query43	319	321	283	283
query44	1465	798	780	780
query45	205	195	179	179
query46	1103	1223	744	744
query47	2412	2316	2260	2260
query48	416	418	305	305
query49	599	426	325	325
query50	1068	431	357	357
query51	11176	10801	10888	10801
query52	88	96	77	77
query53	278	279	206	206
query54	316	252	225	225
query55	76	74	67	67
query56	307	300	299	299
query57	1441	1426	1328	1328
query58	303	285	267	267
query59	1608	1672	1412	1412
query60	317	286	265	265
query61	175	175	212	175
query62	696	644	578	578
query63	245	206	202	202
query64	2544	769	594	594
query65	4908	4785	4751	4751
query66	1796	506	374	374
query67	28880	29548	29304	29304
query68	3106	1562	955	955
query69	414	291	272	272
query70	1063	986	970	970
query71	358	325	309	309
query72	2800	2622	2290	2290
query73	861	880	449	449
query74	5114	5005	4777	4777
query75	2614	2591	2224	2224
query76	2310	1184	762	762
query77	356	378	263	263
query78	12428	12433	11758	11758
query79	1485	1155	787	787
query80	1242	549	440	440
query81	529	323	291	291
query82	627	156	123	123
query83	355	316	293	293
query84	280	152	129	129
query85	935	601	527	527
query86	436	318	290	290
query87	1832	1826	1762	1762
query88	3781	2786	2783	2783
query89	472	409	362	362
query90	1901	211	194	194
query91	202	185	159	159
query92	66	61	58	58
query93	1686	1515	1084	1084
query94	726	354	323	323
query95	778	589	477	477
query96	1146	843	344	344
query97	2682	2686	2578	2578
query98	224	204	198	198
query99	1178	1167	1048	1048
Total cold run time: 265651 ms
Total hot run time: 180194 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 24.89 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit d32f82d4fb8cb82c8f4ee020bba8de29dcf549ab, data reload: false

query1	0.01	0.01	0.00
query2	0.09	0.05	0.05
query3	0.29	0.14	0.13
query4	1.60	0.14	0.14
query5	0.24	0.22	0.22
query6	1.28	1.03	1.08
query7	0.04	0.01	0.01
query8	0.05	0.04	0.04
query9	0.39	0.31	0.33
query10	0.56	0.57	0.54
query11	0.20	0.14	0.14
query12	0.19	0.14	0.15
query13	0.47	0.47	0.49
query14	1.01	1.00	1.00
query15	0.61	0.58	0.59
query16	0.32	0.32	0.31
query17	1.09	1.10	1.10
query18	0.23	0.23	0.21
query19	2.02	1.88	1.97
query20	0.02	0.01	0.02
query21	15.40	0.27	0.15
query22	4.71	0.06	0.05
query23	16.11	0.32	0.12
query24	2.99	0.42	0.32
query25	0.13	0.04	0.03
query26	0.73	0.20	0.15
query27	0.04	0.03	0.03
query28	3.49	0.92	0.54
query29	12.51	4.04	3.24
query30	0.28	0.15	0.15
query31	2.78	0.60	0.31
query32	3.22	0.60	0.50
query33	3.14	3.28	3.19
query34	15.87	4.25	3.52
query35	3.49	3.49	3.48
query36	0.57	0.45	0.43
query37	0.09	0.07	0.06
query38	0.06	0.04	0.04
query39	0.04	0.03	0.03
query40	0.18	0.16	0.15
query41	0.09	0.03	0.03
query42	0.04	0.03	0.03
query43	0.05	0.03	0.03
Total cold run time: 96.72 s
Total hot run time: 24.89 s

@Mryange

Mryange commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 100.00% (60/60) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 56.53% (23202/41042)
Line Coverage 40.09% (225179/561746)
Region Coverage 36.06% (177903/493406)
Branch Coverage 37.09% (79033/213057)

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants