Skip to content

[fix](load) Avoid global BE auth precheck for stream load - #66629

Merged
hello-stephen merged 1 commit into
apache:masterfrom
gavinchou:gavin-cir-21337-streamload-table-load-priv
Aug 12, 2026
Merged

[fix](load) Avoid global BE auth precheck for stream load#66629
hello-stephen merged 1 commit into
apache:masterfrom
gavinchou:gavin-cir-21337-streamload-table-load-priv

Conversation

@gavinchou

@gavinchou gavinchou commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Remove the generic BE HTTP auth precheck from Stream Load, Stream Load 2PC, and HTTP Stream.
  • Keep the existing load-specific path: BE parses Basic auth and FE load RPCs check LOAD against the actual db/table/txn.
  • Add docker regression coverage for table-level and database-level LOAD users with BE enable_all_http_auth both off and on.

Testing

  • sh format_code.sh on changed BE files
  • git diff --check
  • ninja -C be/ut_build_ASAN stream_load.cpp.o stream_load_2pc.cpp.o http_stream.cpp.o
  • run-regression-test selected both new docker suites; local regression config skips docker execution, but framework compilation and suite discovery passed

@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?

@gavinchou

Copy link
Copy Markdown
Contributor Author

/review

@gavinchou

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17689	4008	3934	3934
q2	2083	308	196	196
q3	10256	1405	830	830
q4	4674	463	336	336
q5	7479	855	552	552
q6	172	170	134	134
q7	745	779	597	597
q8	9352	1406	1453	1406
q9	5467	4055	4035	4035
q10	6743	1622	1370	1370
q11	499	352	322	322
q12	734	580	443	443
q13	18156	3248	2727	2727
q14	258	252	242	242
q15	q16	730	730	659	659
q17	1034	1079	808	808
q18	6554	5580	5557	5557
q19	1308	1160	986	986
q20	806	670	560	560
q21	5850	2537	2381	2381
q22	434	351	292	292
Total cold run time: 101023 ms
Total hot run time: 28367 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4256	4176	4160	4160
q2	273	317	208	208
q3	4512	4833	4394	4394
q4	2128	2216	1403	1403
q5	4191	4058	4122	4058
q6	223	172	127	127
q7	1656	1596	1406	1406
q8	2175	2417	2033	2033
q9	7295	7139	7191	7139
q10	4334	4337	3830	3830
q11	538	405	356	356
q12	705	722	521	521
q13	3200	3494	3044	3044
q14	301	299	267	267
q15	q16	709	746	654	654
q17	1295	1296	1300	1296
q18	12171	11087	11747	11087
q19	1163	1121	1134	1121
q20	2245	2214	1955	1955
q21	5645	4751	4908	4751
q22	550	478	430	430
Total cold run time: 59565 ms
Total hot run time: 54240 ms

@hello-stephen

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

query5	4333	596	458	458
query6	460	222	201	201
query7	4853	634	339	339
query8	320	168	151	151
query9	8761	3974	3976	3974
query10	464	359	304	304
query11	5831	2182	1989	1989
query12	148	97	92	92
query13	1248	588	407	407
query14	6064	4235	3924	3924
query14_1	3744	3776	3752	3752
query15	197	197	180	180
query16	985	515	455	455
query17	912	670	522	522
query18	2425	464	332	332
query19	204	183	141	141
query20	103	98	101	98
query21	229	155	133	133
query22	13067	12978	12945	12945
query23	15737	15107	14600	14600
query23_1	14577	14717	14614	14614
query24	7566	1709	1226	1226
query24_1	1245	1231	1230	1230
query25	570	439	384	384
query26	1338	350	214	214
query27	2591	618	395	395
query28	4553	2010	2009	2009
query29	1210	649	490	490
query30	349	257	226	226
query31	1165	1118	1041	1041
query32	118	63	59	59
query33	547	330	268	268
query34	1226	1198	673	673
query35	745	754	644	644
query36	799	790	761	761
query37	160	110	98	98
query38	1865	1813	1743	1743
query39	863	872	833	833
query39_1	773	776	780	776
query40	256	168	148	148
query41	69	69	70	69
query42	94	94	94	94
query43	318	318	280	280
query44	1405	769	758	758
query45	186	173	168	168
query46	1066	1177	739	739
query47	1534	1579	1444	1444
query48	417	416	295	295
query49	589	416	298	298
query50	1122	433	341	341
query51	10839	10759	10601	10601
query52	88	89	78	78
query53	263	288	199	199
query54	301	245	242	242
query55	76	73	70	70
query56	312	320	293	293
query57	1025	1015	911	911
query58	314	250	258	250
query59	1575	1641	1403	1403
query60	321	277	265	265
query61	173	178	167	167
query62	402	319	266	266
query63	241	201	199	199
query64	2883	1010	852	852
query65	3864	3820	3777	3777
query66	1843	480	353	353
query67	19994	20069	19878	19878
query68	3215	1605	983	983
query69	393	287	254	254
query70	865	779	753	753
query71	365	335	329	329
query72	2977	2570	2282	2282
query73	847	751	456	456
query74	4594	4480	4280	4280
query75	2364	2369	1983	1983
query76	2343	1158	780	780
query77	342	363	266	266
query78	11036	11145	10536	10536
query79	1393	1100	759	759
query80	1252	536	450	450
query81	519	328	280	280
query82	633	171	136	136
query83	380	321	288	288
query84	321	161	132	132
query85	963	586	533	533
query86	416	227	212	212
query87	1973	1929	1850	1850
query88	3706	2797	2767	2767
query89	397	320	277	277
query90	1891	200	197	197
query91	199	189	160	160
query92	60	59	52	52
query93	1655	1508	1036	1036
query94	717	355	299	299
query95	776	591	456	456
query96	1115	757	338	338
query97	2458	2450	2352	2352
query98	194	194	179	179
query99	739	759	613	613
Total cold run time: 245196 ms
Total hot run time: 158317 ms

@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.

Request changes.

The common direct-BE stream-load path is now table-scoped, but three blocking gaps remain: 2PC authorization is not bound to the selected transaction, cloud group-commit forwarding retains the global gate, and the added FE-redirect regression never reaches a redirect.

Critical checkpoints:

  • Goal and proof: The direct BE path and ordinary FE-redirect design use table-level LOAD, and the table-specific 2PC happy path is wired, but the transaction and forwarding gaps leave the goal incomplete; the redirect test does not currently prove its path.
  • Scope and reuse: The request-local helper is focused, but /_stream_load_forward is a functional parallel path and should share the same target-scoped policy instead of retaining a separate global check.
  • Concurrency and lifecycle: The overrides add only request-owned data and local Thrift objects. No new shared mutable state, locks, threads, ownership transfer, teardown path, or nontrivial static-initialization dependency was introduced.
  • Configuration and compatibility: No protocol, persisted format, or new configuration changes. The documented database-level fallback for the legacy 2PC route remains intentional; the defects appear on existing all-HTTP-auth, cloud 2PC, and group-forward configurations.
  • Transactions, data correctness, and RBAC: FE-backed live-table 2PC checks actual targets, but the cloud txn-ID abort path bypasses that binding and can operate an unrelated transaction. Authorization must be tied to the transaction's recorded target set.
  • Tests: The new suite covers common allow/deny and matching 2PC commit intent, but the FE request lacks the mandatory Expect: 100-continue; mismatched transaction-target abort and multi-BE group-forward cases are also needed. No builds or test suites were run locally because the review bundle prohibits them. At the final refresh, compile, formatter, Checkstyle, license, and secret checks passed; BE and regression suites were still pending.
  • Performance, observability, and persistence: The bounded decoding/object construction adds no material hot-path or synchronization concern. There are no EditLog, storage-format, or observability changes.
  • User focus: No additional review focus was supplied.
  • Convergence: After the three findings were validated and deduplicated, every normal and risk-focused reviewer in round 2 returned NO_NEW_VALUABLE_FINDINGS.

if (table.empty()) {
priv_ctrl.__set_priv_hier(TPrivilegeHier::DATABASE);
} else {
priv_ctrl.__set_priv_hier(TPrivilegeHier::TABLE);

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.

[P1] Bind 2PC authorization to the selected transaction

This authorizes only the caller-controlled table in the URL, but handle() discards that table. In cloud mode, every txn-ID abort goes through CloudStreamLoadExecutor::operate_txn_2pc() to CloudMetaMgr::abort_txn(), which sends only the instance credential and txn ID; Meta Service then resolves and aborts the real transaction without a user/table check. A user with LOAD on db.allowed can therefore call /api/db/allowed/_stream_load_2pc with another live precommitted transaction ID—even from another database in the same instance—and abort it. Bind the check to the transaction's recorded tables (or force this operation through the FE transaction-aware path), and add a mismatched URL-table/transaction abort test.

}
return 0;
}

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.

[P1] Apply table-scoped auth to the forwarding route

Cloud group commit redirects through /_stream_load_forward when the selected endpoint differs from the table's target BE. StreamLoadForwardHandler still constructs the base handler with GLOBAL/LOAD and performs that check before forwarding, so with all-HTTP-auth and group forwarding enabled a table-only user is rejected at the proxy and never reaches this updated handler. Share the same target-bound policy with the forward handler while keeping it aligned with the forwarded path, and cover the multi-BE forwarding branch.

"curl", "--noproxy", "*", "-sS", "-w", "\n%{http_code}",
"-u", "${user}:${pwd}",
"-H", "label:${label}",
"-H", "column_separator:,",

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.

[P1] Send the required Expect header before testing FE redirect

LoadAction.executeWithoutPassword() returns There is no 100-continue header before selecting a backend. This fixture is only 18 bytes, and curl 8.5.0 sends Content-Length: 18 but no Expect for this -T upload, so the redirected call gets an HTTP-200 failed REST body and redirectedJson.Status is absent. Add the header so the assertion actually reaches BE authorization.

Suggested change
"-H", "column_separator:,",
"-H", "column_separator:,",
"-H", "Expect:100-continue",

@hello-stephen

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

query1	0.01	0.01	0.00
query2	0.10	0.05	0.05
query3	0.25	0.13	0.13
query4	1.62	0.13	0.13
query5	0.24	0.22	0.23
query6	1.17	0.82	0.81
query7	0.04	0.01	0.00
query8	0.05	0.04	0.03
query9	0.38	0.32	0.31
query10	0.58	0.55	0.59
query11	0.19	0.13	0.14
query12	0.18	0.14	0.13
query13	0.45	0.47	0.48
query14	1.00	1.00	0.99
query15	0.60	0.58	0.59
query16	0.33	0.32	0.31
query17	1.07	1.11	1.11
query18	0.21	0.19	0.19
query19	2.02	1.93	1.96
query20	0.02	0.01	0.01
query21	15.43	0.18	0.15
query22	4.99	0.06	0.05
query23	16.10	0.31	0.12
query24	2.94	0.42	0.33
query25	0.10	0.05	0.03
query26	0.73	0.21	0.15
query27	0.04	0.04	0.05
query28	3.56	0.79	0.36
query29	12.48	4.08	3.21
query30	0.28	0.15	0.16
query31	2.77	0.55	0.31
query32	3.22	0.59	0.49
query33	3.21	3.18	3.14
query34	15.50	3.92	3.25
query35	3.20	3.19	3.21
query36	0.55	0.44	0.45
query37	0.09	0.07	0.06
query38	0.05	0.04	0.04
query39	0.04	0.03	0.03
query40	0.17	0.16	0.15
query41	0.08	0.03	0.03
query42	0.04	0.03	0.04
query43	0.04	0.03	0.04
Total cold run time: 96.12 s
Total hot run time: 23.86 s

@gavinchou

Copy link
Copy Markdown
Contributor Author

fix #60761

@bobhan1 bobhan1 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.

The common direct-BE Stream Load path and the ordinary FE 307 redirect path now look correctly scoped to TABLE/LOAD. However, I think two compatibility/correctness gaps remain:

  1. The legacy database-only 2PC endpoint still rejects users that only have table-level LOAD_PRIV. When the request is /api/{db}/_stream_load_2pc, set_load_privilege() maps it to DATABASE/LOAD. checkDbPriv(..., LOAD) does not consider a table-level grant, even though FrontendServiceImpl.loadTxn2PCImpl() subsequently resolves the transaction's actual table list and checks LOAD on every table. As a result, a table-only user that could use this endpoint before the generic HTTP pre-auth change still receives 403. This route is still used by the regression framework (regression-test/framework/src/main/groovy/org/apache/doris/regression/action/StreamLoadAction.groovy:303), so it is not only a dead compatibility route. For the database-only form, please consider doing authentication-only at the BE and relying on the existing transaction-bound FE checks, or otherwise authorize against the transaction's actual tables. A regression case using the database-only 2PC URL with only table-level LOAD_PRIV would cover this.

  2. Cloud group-commit forwarding still goes through a GLOBAL/LOAD gate. StreamLoadForwardHandler is still constructed with HttpHandlerWithAuth(exec_env, TPrivilegeHier::GLOBAL, TPrivilegeType::LOAD), and its on_header() calls the parent check before forwarding. With enable_all_http_auth=true and group-commit forwarding enabled, a table-only user can therefore receive 403 on the first BE and never reach the table-scoped StreamLoadAction fixed by this PR. Please apply the same db/table-based TABLE/LOAD policy to /_stream_load_forward and add a forwarding-path regression case.

These are residual paths rather than regressions introduced by the new table-scoped implementation, but they leave valid Stream Load flows inconsistent under all-HTTP-auth.

@gavinchou
gavinchou force-pushed the gavin-cir-21337-streamload-table-load-priv branch from 0139c27 to bd12e5a Compare August 11, 2026 03:51
@gavinchou gavinchou changed the title [fix](load) Check BE stream load auth at table scope [fix](load) Avoid global BE auth precheck for stream load Aug 11, 2026
@gavinchou

Copy link
Copy Markdown
Contributor Author

run buildall

@gavinchou

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.

Request changes.

The ordinary direct-BE, non-group Stream Load path now delegates to FE table-scoped authorization, but removing the common hook from three handlers is not safe across their parallel execution paths. Four new blocking issues remain: public auth_code becomes a trusted credential marker; explicit/config-forced group commit skips the only target LOAD check; HTTP Stream authorizes before it has both a verified identity and resolved target; and cloud label abort discards FE failure while reporting success.

The existing threads already own the cloud txn-ID transaction-binding issue (including its optional direct-commit sibling), the group-forward handler's GLOBAL gate, and the missing Expect: 100-continue test precondition. I did not duplicate those comments.

Critical checkpoint conclusions:

  • Goal and proof: The stated goal is only achieved for ordinary non-group Stream Load with normal Basic credentials (and table-property group commit, which authenticates before FE selects the mode). The four inline findings show that the common downstream-auth premise does not hold for all three changed handlers. The new test does not prove those variants.
  • Scope and reuse: The inheritance edits are mechanically small and focused, but a blanket removal is not the smallest correct policy because the handlers do not share one equivalent downstream authorization boundary. A verified identity plus resolved-target check should be reused at the actual common planning/transaction boundaries.
  • Concurrency and thread safety: No new thread, shared mutable state, lock, atomic, or lock-order change is introduced. Request contexts and metrics retain their existing threading model; no new deadlock or heavy-under-lock issue was found.
  • Lifecycle and static initialization: The added raw ExecEnv* members are non-owning replacements for the inherited pointer and do not change destruction order or ownership. No circular ownership, cross-TU static initialization, or teardown issue was introduced. HTTP Stream's existing FE-created transaction lifecycle does expose the pending-transaction consequence described inline when token validation is delayed until commit.
  • Configuration: No new configuration is added. Existing enable_all_http_auth, wait_internal_group_commit_finish, enable_stream_load_commit_txn_on_be, group-forwarding, cloud/shared-nothing, and TSO fences materially select different authorization paths; the implementation and tests do not cover them consistently.
  • Compatibility: No Thrift/storage format, persisted state, function ABI, or rolling-upgrade protocol change is added. Behavior compatibility is nevertheless broken for scoped HTTP Stream users, and enabling all-HTTP-auth no longer gates the legacy/token forms on these handlers.
  • Parallel paths and conditions: Normal versus explicit/forced/table-property group commit, HTTP Stream, FE redirect, BE forwarding, and 2PC label versus txn-ID commit/abort were traced. Table-property group commit and FE-routed transaction-aware 2PC are the safe counterexamples; the accepted and existing comments cover the unsafe branches. The condition comments in the patch overstate FE coverage for those branches.
  • Test coverage: The cloud one-BE suites cover only ordinary Basic direct-BE allow/deny before their FE upload. They omit explicit/forced and table-property group commit, HTTP Stream, auth_code/invalid token, label abort, mismatched transaction, multi-BE forwarding, shared-nothing, TSO, and direct cloud commit. One BE cannot exercise forwarding.
  • Test results: The 18-byte FE upload lacks the mandatory Expect: 100-continue, so the already-reported assertion fails before redirect and later statements in each suite are unreachable. No expected-result file is changed. I did not build or run tests because the authoritative review prompt forbids it; the PR description also says the docker suite was not executed.
  • Error handling, memory safety, and data correctness: No new buffer ownership, allocation, nullable-column, or memory-accounting issue was found. Error propagation is incorrect in cloud label abort because TLoadTxnRollbackResult.status is ignored. Authorization gaps can admit writes, and false success can leave a PRECOMMITTED transaction unchanged.
  • Transactions, persistence, and data writes: No EditLog schema or persistence path changes. Ordinary transaction mechanics and failover handling are unchanged, but authorization must precede planning/mutation and be bound to the transaction's recorded tables. The label-abort result must be propagated so the response matches transaction state.
  • FE/BE variable propagation: No new cross-process field is introduced. Existing auth_code, token, db/table, SQL, label, and txn-ID fields are populated inconsistently across the changed routes; the inline findings identify the missing trusted-identity/target bindings.
  • Observability: Existing request, load, and transaction logs/metrics are sufficient to diagnose these paths; no separate observability blocker was found. Returning Success for rejected label abort is itself misleading and must be fixed rather than masked with logging.
  • Performance: Removing one redundant auth RPC is beneficial only where an equivalent target-bound check exists. No separate CPU, memory, I/O, or hot-lock regression was found; restoring authorization at the common boundaries should remain bounded per request.
  • Other/security boundary: Under Doris's threat model, direct BE HTTP on port 8040 is a Zone-2/internal surface, so the direct-only variants are reported as supported-workflow authorization/correctness regressions, not as claims of internet-exposed vulnerabilities. FE-routed scoped-user rejection and cloud label-abort false success also remain relevant after normal FE authentication.
  • User focus: No additional user-provided review focus was supplied; the full PR was reviewed.
  • Completion: The review converged in two rounds. Both normal full-coverage reviewers and the separate risk-focused reviewer returned NO_NEW_VALUABLE_FINDINGS after the HTTP Stream token scope was narrowed to the verified explicit/config-forced group-commit trigger. All candidates are accepted, merged, or duplicate-fenced.

: HttpHandlerWithAuth(exec_env, TPrivilegeHier::GLOBAL, TPrivilegeType::LOAD) {
// Use LOAD privilege type: requires LOAD permission
StreamLoadAction::StreamLoadAction(ExecEnv* exec_env) : _exec_env(exec_env) {
// Stream load forwards the parsed HTTP credentials to FE load RPCs, where LOAD

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.

[P1] Do not trust the public auth_code header

With enable_all_http_auth=true, parse_basic_auth(AuthInfo*) accepts any numeric auth_code without Basic credentials and set_request_auth() forwards it. FE loadTxnBeginImpl() and loadTxnRollbackImpl() treat isSetAuthCode() as a deprecated trusted path and skip password, token, and LOAD checks, so auth_code: 0 can perform an ordinary direct-BE load and a cloud label abort. The removed hook previously sent this form through checkAuth with empty credentials and rejected it. Remove or gate the public legacy header, or establish a verified identity and resolved target before setting the trusted field; add negative normal-load and label-abort tests.

StreamLoadAction::StreamLoadAction(ExecEnv* exec_env) : _exec_env(exec_env) {
// Stream load forwards the parsed HTTP credentials to FE load RPCs, where LOAD
// privilege is checked against the actual db/table/txn. A generic BE HTTP
// pre-check cannot model every stream-load variant and would duplicate that

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.

[P1] Authenticate explicit group commit before planning

_handle_group_commit() sets ctx->group_commit for explicit sync/async mode and for wait_internal_group_commit_finish before _on_header(), so the loadTxnBegin() RPC is skipped. That RPC is the only ordinary password and table-LOAD check: the remaining FE planning path calls analyzeWithoutCheckPriv(). A direct-BE request can therefore group-commit with a wrong password in shared-nothing, or as a cloud user with compute-group access but no LOAD on the target. Table-property group commit is safe because it authenticates before FE selects the mode. Put target-bound authentication on the common group-planning boundary and add explicit/forced cloud and shared-nothing negative tests.

// Use LOAD privilege type: requires LOAD permission
// Note: _exec_env is set by parent class HttpHandlerWithAuth
HttpStreamAction::HttpStreamAction(ExecEnv* exec_env) : _exec_env(exec_env) {
// HTTP stream derives db/table from the SQL header and then forwards the

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.

[P1] Establish the HTTP Stream identity before target planning

/api/_http_stream has no db/table path fields, and this handler forwards load_sql without populating request db/tbl. FE therefore rejects valid table- or database-scoped Basic users against empty strings before parsing the SQL target. Conversely, merely setting Auth-Token skips that precheck and installs the Basic username as ConnectContext identity without validating the token or password. Ordinary mode catches a junk token only at final commit, after staging a transaction with no immediate rollback; explicit/config-forced group commit skips that boundary and can complete as the claimed user. Authenticate first, resolve the SQL target, then check LOAD on it, with scoped-user and invalid-token group tests.

// Use LOAD privilege type: requires LOAD permission
// Note: _exec_env is set by parent class HttpHandlerWithAuth
StreamLoad2PCAction::StreamLoad2PCAction(ExecEnv* exec_env) : _exec_env(exec_env) {
// 2PC commit/abort resolves the transaction's table list in FE and checks LOAD

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.

[P1] Propagate the label-abort failure instead of returning Success

In cloud mode, a label-based abort reaches generic rollback_txn() with tbl="" because this handler records the database and label but not the route table. FE rejects a table-scoped user on that empty table before resolving the label, but the BE ignores TLoadTxnRollbackResult.status; CloudStreamLoadExecutor then returns OK and this handler reports Success while the transaction remains PRECOMMITTED. Route label abort through transaction-aware 2PC authorization, or return and propagate the rollback status after resolving the transaction tables, and assert both response and transaction state in a label-abort test.

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17609	3993	3992	3992
q2	2065	338	205	205
q3	10321	1398	830	830
q4	4683	471	336	336
q5	7544	851	558	558
q6	191	182	141	141
q7	739	804	609	609
q8	9419	1580	1525	1525
q9	5398	4089	4067	4067
q10	6793	1623	1343	1343
q11	507	359	333	333
q12	714	585	464	464
q13	18143	3299	2810	2810
q14	267	262	244	244
q15	q16	737	734	671	671
q17	1013	1019	1017	1017
q18	6586	5630	5540	5540
q19	1288	1190	1110	1110
q20	850	708	590	590
q21	6145	2809	2642	2642
q22	464	394	337	337
Total cold run time: 101476 ms
Total hot run time: 29364 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5055	4570	4640	4570
q2	296	334	231	231
q3	4903	5223	4644	4644
q4	2191	2275	1413	1413
q5	4717	4487	4452	4452
q6	234	179	131	131
q7	1855	1743	1503	1503
q8	2361	2114	2237	2114
q9	7277	6887	6753	6753
q10	4239	4184	3842	3842
q11	536	393	353	353
q12	689	709	502	502
q13	2963	3331	2777	2777
q14	276	288	244	244
q15	q16	649	691	611	611
q17	1246	1246	1261	1246
q18	12155	10999	11836	10999
q19	1122	1085	1101	1085
q20	2208	2182	1903	1903
q21	5293	4529	4674	4529
q22	534	482	408	408
Total cold run time: 60799 ms
Total hot run time: 54310 ms

@hello-stephen

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

query5	4317	586	469	469
query6	483	225	202	202
query7	4904	588	338	338
query8	327	161	148	148
query9	8804	4068	4080	4068
query10	501	366	305	305
query11	5845	2216	2000	2000
query12	162	97	99	97
query13	1258	597	434	434
query14	6079	4285	3973	3973
query14_1	3819	3779	3758	3758
query15	197	189	170	170
query16	970	455	438	438
query17	902	668	524	524
query18	2428	447	319	319
query19	203	176	136	136
query20	99	99	99	99
query21	229	151	135	135
query22	12967	12949	12746	12746
query23	15634	15144	14539	14539
query23_1	14707	14654	14696	14654
query24	7558	1718	1227	1227
query24_1	1275	1260	1272	1260
query25	564	454	388	388
query26	1322	358	212	212
query27	2597	577	373	373
query28	4585	2064	2003	2003
query29	1103	631	510	510
query30	339	272	227	227
query31	1171	1125	1060	1060
query32	111	62	61	61
query33	530	328	252	252
query34	1203	1161	639	639
query35	740	752	640	640
query36	750	769	712	712
query37	161	114	98	98
query38	1818	1796	1688	1688
query39	835	824	795	795
query39_1	787	779	791	779
query40	257	170	149	149
query41	72	72	70	70
query42	105	96	95	95
query43	321	321	280	280
query44	1419	754	764	754
query45	186	176	175	175
query46	1073	1141	740	740
query47	1544	1501	1450	1450
query48	409	406	300	300
query49	594	413	315	315
query50	1075	422	328	328
query51	10736	10356	10561	10356
query52	89	90	77	77
query53	253	278	211	211
query54	297	244	235	235
query55	78	77	67	67
query56	310	310	319	310
query57	1025	996	945	945
query58	301	275	272	272
query59	1567	1625	1373	1373
query60	316	288	266	266
query61	179	202	145	145
query62	393	325	263	263
query63	241	196	200	196
query64	2849	1015	836	836
query65	3877	3765	3795	3765
query66	1832	458	357	357
query67	20170	20259	20053	20053
query68	3120	1561	1041	1041
query69	397	297	268	268
query70	860	757	777	757
query71	380	348	332	332
query72	3029	2674	2337	2337
query73	850	749	427	427
query74	4636	4502	4310	4310
query75	2369	2335	2004	2004
query76	2333	1141	726	726
query77	338	357	274	274
query78	11212	11081	10500	10500
query79	1305	1181	774	774
query80	653	543	456	456
query81	528	333	277	277
query82	626	166	143	143
query83	400	319	295	295
query84	332	163	126	126
query85	959	602	524	524
query86	318	236	230	230
query87	1985	1950	1847	1847
query88	3664	2789	2779	2779
query89	371	323	283	283
query90	1918	191	196	191
query91	201	192	155	155
query92	60	57	53	53
query93	1528	1468	935	935
query94	544	347	325	325
query95	783	601	477	477
query96	1039	791	355	355
query97	2545	2451	2322	2322
query98	194	194	189	189
query99	737	740	619	619
Total cold run time: 244315 ms
Total hot run time: 158300 ms

@hello-stephen

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

query1	0.00	0.00	0.00
query2	0.09	0.04	0.04
query3	0.26	0.14	0.13
query4	1.60	0.15	0.14
query5	0.25	0.22	0.21
query6	1.15	0.80	0.78
query7	0.05	0.01	0.00
query8	0.06	0.03	0.03
query9	0.36	0.31	0.32
query10	0.55	0.58	0.57
query11	0.19	0.13	0.13
query12	0.18	0.15	0.14
query13	0.47	0.47	0.47
query14	1.00	1.00	0.99
query15	0.59	0.59	0.59
query16	0.33	0.32	0.31
query17	1.07	1.08	1.09
query18	0.21	0.20	0.19
query19	2.03	1.96	1.94
query20	0.01	0.01	0.01
query21	15.46	0.21	0.13
query22	4.91	0.05	0.05
query23	16.13	0.30	0.12
query24	3.34	0.43	0.33
query25	0.11	0.05	0.05
query26	0.76	0.21	0.14
query27	0.06	0.03	0.03
query28	3.49	0.74	0.34
query29	12.55	4.05	3.19
query30	0.27	0.16	0.16
query31	2.77	0.55	0.32
query32	3.22	0.59	0.49
query33	3.20	3.27	3.18
query34	15.56	3.97	3.28
query35	3.19	3.22	3.27
query36	0.55	0.45	0.43
query37	0.09	0.07	0.06
query38	0.06	0.05	0.03
query39	0.04	0.03	0.04
query40	0.16	0.16	0.14
query41	0.08	0.04	0.03
query42	0.04	0.02	0.02
query43	0.04	0.04	0.03
Total cold run time: 96.53 s
Total hot run time: 23.86 s

@liaoxin01 liaoxin01 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 Aug 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

@hello-stephen

Copy link
Copy Markdown
Contributor

skip check_coverage

@hello-stephen
hello-stephen merged commit c9f2dd6 into apache:master Aug 12, 2026
34 checks passed
wyxxxcat pushed a commit to wyxxxcat/doris that referenced this pull request Aug 17, 2026
## Summary
- Remove the generic BE HTTP auth precheck from Stream Load, Stream Load
2PC, and HTTP Stream.
- Keep the existing load-specific path: BE parses Basic auth and FE load
RPCs check LOAD against the actual db/table/txn.
- Add docker regression coverage for table-level and database-level LOAD
users with BE enable_all_http_auth both off and on.

## Testing
- sh format_code.sh on changed BE files
- git diff --check
- ninja -C be/ut_build_ASAN stream_load.cpp.o stream_load_2pc.cpp.o
http_stream.cpp.o
- run-regression-test selected both new docker suites; local regression
config skips docker execution, but framework compilation and suite
discovery passed

Co-authored-by: gavinchou <gavinchou@apache.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by one committer. dev/4.1.x dev/4.1.x-conflict

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants