Skip to content

[fix](docker)(case) Fix kerberized-HDFS p2 suites: SASL client property, Paimon fixture, iceberg root-cause reporting - #66433

Merged
morningman merged 3 commits into
apache:masterfrom
morningman:fix/master-external-kerberos-paimon-iceberg
Aug 5, 2026
Merged

[fix](docker)(case) Fix kerberized-HDFS p2 suites: SASL client property, Paimon fixture, iceberg root-cause reporting#66433
morningman merged 3 commits into
apache:masterfrom
morningman:fix/master-external-kerberos-paimon-iceberg

Conversation

@morningman

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: close #xxx

Related PR: #65564, #66313, #66417

Problem Summary:

Master port of the remaining external-regression gaps diagnosed on the
branch-4.0 pipeline (#66417). #66313 already carried the keytab and baseline
fixes to master; this PR carries the rest. All three defects were verified to
exist on master by inspection — master shares the same code and the same
lightweight Kerberos environment (#65564, which #65939 backported to 4.0).

1. Kerberos HDFS writes fail in the p2 suites (SASL client property missing)

#65564 created kerberos/conf/hdfs-site.xml.tpl with
dfs.data.transfer.protection=authentication. A client that does not set the
same property sends a plain writeBlock op, SaslDataTransferServer closes the
socket, the client excludes the only DataNode, and the write fails with

could only be written to 0 of the 1 minReplication nodes.
There are 1 datanode(s) running and 1 node(s) are excluded in this operation.

(through iceberg this surfaces as IllegalArgumentException: Self-suppression not permitted). Metadata operations only reach the NameNode and the HMS, so
CREATE DATABASE / CREATE TABLE still succeed and only the write fails.
#65564 set the client property in the four external_table_p0/kerberos suites
but not in the p2 suites that talk to the same kerberized HDFS. On the
branch-4.0 pipeline this turned hive_on_hms_and_dlf and
iceberg_on_hms_and_filesystem_and_dlf red on every run; master carries the
identical omission.

Fix: set dfs.data.transfer.protection in every property block that points at
the kerberized HDFS. A scan of :8520/:8620 across the whole suite tree finds
seven such blocks still missing it: two each in hive_on_hms_and_dlf,
iceberg_on_hms_and_filesystem_and_dlf and test_paimon_hms_catalog, plus one
in hdfs_all_test (currently returns early because
refactor_params_hdfs_kerberos_test is unset — it would fail the moment it is
enabled). The kerberos block of test_information_schema_timezone has the same
gap but is disabled by an unrelated TODO, so it is left alone.

2. test_paimon_hms_catalog: Unknown database 'hdfs_db'

The lightweight Kerberos environment starts an empty metastore — schematool -initSchema and nothing else. The environment it replaced uploaded
paimon_data into HDFS and registered hdfs_db through
create_paimon_hive_table.hql on every start; paimon_data/hdfs_db.db/ is
still in the tree but the compose file never mounted it. This restores the
fixture on kerberos1 only (it owns metastore 9583, the only one the suite
talks to), runs it before DORIS_KERBEROS_READY so nothing races the suites,
and aborts the container on failure instead of handing out an environment
silently missing hdfs_db.

Two deliberate differences from the branch-4.0 sibling commit:

3. IcebergConnectorMetadata: report the root cause of failed metadata commits

TableMetadataParser.internalWrite writes the metadata JSON inside
try-with-resources, and DFSOutputStream throws the same exception instance
from write and from close once its pipeline has failed, so
Throwable.addSuppressed(this) replaces the failure with
IllegalArgumentException: Self-suppression not permitted. The FE log keeps the
chain, but the message returned over the MySQL protocol is built from
e.getMessage() and carries only the wrapper.

This switches all nineteen metadata-commit paths — createTable, the
column/schema updates (including the nested-column and comment variants), the
branch/tag operations, and the partition-field operations — to
ExceptionUtils.getRootCauseMessage(e). The legacy IcebergMetadataOps
already reported the root cause for the partition-field trio; the connector
rewrite lost that, so this also restores it. Read paths and the drop/rename
operations cannot hit self-suppression and keep e.getMessage().

Intentionally not ported from #66417: the file-cache de-flake. Master's
test_file_cache_features (rewritten in #66313's lineage) already waits for
disk_resource_limit_mode / need_evict_cache_in_advance to clear before
returning, which closes the residual-state window at its source.

Verification (local): fe-connector-iceberg compiles and passes checkstyle
(mvn -pl fe-connector/fe-connector-iceberg package); the four changed suites
compile with the offline groovy compiler; bash -n passes on both shell
scripts; the compose/env/conf templates render with no leftover placeholders,
the rendered XML parses, kerberos1 gets exactly the three new mounts while
kerberos2 is unchanged; the settings resolution and the entrypoint role-gate
were exercised for all switch/role combinations. The containers themselves need
the CI environment and have not been run.

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.

apache#65564 rebuilt the Kerberos test environment and created
`kerberos/conf/hdfs-site.xml.tpl` with

    dfs.data.transfer.protection=authentication

The environment it replaced carried its server configuration inside the
starburstdata image, so this server-side requirement is new. A client that
does not set the same property sends a plain writeBlock op,
`SaslDataTransferServer` does not find the SASL magic number and closes the
socket, the client excludes the only DataNode, and the next `addBlock` has
no target left. Metadata operations only reach the NameNode and the HMS, so
`CREATE DATABASE`/`CREATE TABLE` still succeed and only the write fails:

    could only be written to 0 of the 1 minReplication nodes.
    There are 1 datanode(s) running and 1 node(s) are excluded in this
    operation.

with `jni.log` showing why the DataNode was excluded - the socket was
established and the server closed it:

    java.net.SocketException: Connection reset
        at DataStreamer.createBlockOutputStream(DataStreamer.java:1931)
    Excluding datanode DatanodeInfoWithStorage[<ip>:9566,...]

(Through iceberg the same failure surfaces as `IllegalArgumentException:
Self-suppression not permitted`, which is what
`TableMetadataParser.internalWrite` turns it into when try-with-resources
calls `Throwable.addSuppressed(this)`.)

apache#65564 set the client property in the four `external_table_p0/kerberos`
suites but not in the p2 suites that talk to the same kerberized HDFS. The
gap was diagnosed on the branch-4.0 external pipeline, where the backport
(apache#65939) turned `hive_on_hms_and_dlf` and
`iceberg_on_hms_and_filesystem_and_dlf` red on every run with exactly these
two signatures; master carries the identical omission.

Fix: set `dfs.data.transfer.protection` in every property block that points
at the kerberized HDFS. A scan of `:8520`/`:8620` across the whole suite
tree finds seven such blocks still missing it: two each in
`hive_on_hms_and_dlf`, `iceberg_on_hms_and_filesystem_and_dlf` and
`test_paimon_hms_catalog`, plus one in `hdfs_all_test`, which writes to
HDFS but currently returns early because
`refactor_params_hdfs_kerberos_test` is unset - it would fail the moment it
is enabled. The kerberos block of `test_information_schema_timezone` has
the same gap but is disabled by an unrelated TODO, so it is left alone.

`test_paimon_hms_catalog` needs one more thing to go green: the lightweight
kerberos container starts an empty metastore, so `hdfs_db` does not exist
there. That is an environment change and comes in a separate commit.

Signed-off-by: morningman <yunyou@selectdb.com>
Creating an Iceberg table on a kerberized HDFS whose DataNode rejected the
write surfaces only

    Self-suppression not permitted

to the user, which says nothing about what went wrong (diagnosed on
branch-4.0; master wraps the same way through `DorisConnectorException`).
`TableMetadataParser.internalWrite` writes the metadata JSON inside
try-with-resources, and `DFSOutputStream` throws the same exception instance
from `write` and from `close` once its pipeline has failed, so the generated
`addSuppressed` call becomes `addSuppressed(this)` and `Throwable` replaces
the failure with `IllegalArgumentException: Self-suppression not permitted`.
The real error is one level down:

    Caused by: RemoteException: ... could only be written to 0 of the 1
    minReplication nodes. There are 1 datanode(s) running and 1 node(s) are
    excluded in this operation.

`IcebergConnectorMetadata` passes the exception as the cause, so the
frontend log keeps that chain, but the message returned over the MySQL
protocol is built from `e.getMessage()` and therefore carries only the
wrapper.

Every path that commits Iceberg table metadata goes through the same parser
and can be masked the same way. This switches all nineteen commit paths -
`createTable`, the column and schema updates (including the nested-column
and comment variants), the branch and tag operations, and the
partition-field operations - to `ExceptionUtils.getRootCauseMessage(e)`.
The legacy `IcebergMetadataOps` already reported the root cause for the
partition-field trio; the connector rewrite lost that, so this also
restores it.

The surrounding message is a literal prefix that already names the
operation and the object, so replacing only the trailing part loses no
context, and no regression case asserts on this text.

Read paths such as `getTableHandle`, `loadTable` and `listTableNames`
cannot hit self-suppression and keep `e.getMessage()`. So do `dropTable`,
`renameTable`, `dropView` and the database operations: they delete or
alter existing objects instead of writing a metadata file through the
parser.

Signed-off-by: morningman <yunyou@selectdb.com>
…tore

The hdfs_kerberos and hdfs_new_kerberos cases of test_paimon_hms_catalog
fail with `Unknown database 'hdfs_db'`, and the suite aborts on the first of
them. The lightweight Kerberos environment from apache#65564 starts an empty
metastore - `schematool -dbType derby -initSchema` and nothing else. The
environment it replaced provisioned the Paimon fixture on every start:

    hadoop fs -put /tmp/paimon_data/* /user/hive/warehouse/
    hive -f /usr/local/sql/create_paimon_hive_table.hql

along with the Paimon storage-handler jar it downloaded into the image's
hive auxlib. None of that survived. `paimon_data/hdfs_db.db/` is still in
the tree but the compose file never mounted it, so it has been dead weight
since the migration. (Diagnosed on the branch-4.0 external pipeline, whose
backport of the same migration broke the same cases; the branch-4.0
counterpart of this fix is in apache#66417.)

This restores the fixture on kerberos1 only - it owns metastore 9583, which
is the only one the suite talks to, so kerberos2 stays as light as it is
today. Both containers run the same entrypoint with the same rendered env
switch, so the fixture is additionally gated on the container role (HOST):
kerberos2 has neither the mounts nor a consumer, and without that gate
`set -e` would abort it the moment the switch is on. Gating on the role
rather than on the mounts keeps a broken mount on kerberos1 failing loudly.

`hdfs_db` is backed by `paimon_data`, uploaded into HDFS before the
metastore is advertised. The table declares no columns, so the metastore
derives the schema through the storage handler
(`metastore.storage.schema.reader.impl` is `SerDeStorageSchemaReader`);
`HIVE_AUX_JARS_PATH` is therefore exported before the metastore starts, not
just around the DDL.

Unlike the branch-4.0 sibling, this does not register `ali_db` over OSS -
and the environment this restores never had it on master: the pre-apache#65564
HQL provisioned exactly `hdfs_db`. The oss_hms_kerberos case that reads
`ali_db` through this metastore exists only on branch-4.0, master's ali_db
cases go through the Hive3 metastore, and the golden output here carries
only the hdfs_kerberos and hdfs_new_kerberos blocks. Skipping it keeps the
jindo/aliyun jars and the OSS credentials out of the kerberos stack and
removes a start-time network dependency no case exercises.

The fixture runs before `DORIS_KERBEROS_READY`, because
`run-thirdparties-docker.sh` releases the pipeline on that marker and
anything published afterwards would race the suites. A failure aborts the
container instead of handing out an environment silently missing `hdfs_db`.

`enablePaimonHms` is read from `hive-3x_settings.env`, the file the
pipeline already patches, rather than copied into `kerberos*_settings.env`
where the two would drift and one stack would quietly lose the fixture. It
is sourced in a subshell so that the Hive3 ports cannot leak into the
Kerberos settings sourced immediately after.

Verified locally: `bash -n` passes on both scripts; the templates and the
compose file render with no leftover placeholders and the rendered XML
parses; the rendered compose gives kerberos1 exactly the three extra mounts
and leaves kerberos2 untouched; the rendered env files carry the right HOST
and enablePaimonHms per container; the settings resolution was exercised
for the enabled, disabled and missing-file cases with an assertion that the
Hive3 ports do not leak; and the entrypoint gate was exercised for both
container roles and both switch values. The golden output already contains
the hdfs_kerberos and hdfs_new_kerberos blocks, so no baseline has to be
regenerated. The container itself needs the CI environment and has not been
run.

Signed-off-by: morningman <yunyou@selectdb.com>
@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?

morningman added a commit to morningman/doris that referenced this pull request Aug 4, 2026
Both kerberos containers run entrypoint-hive-master.sh, and hadoop-hive-1.env
and hadoop-hive-2.env are rendered from the same template with the same host
environment, so kerberos2 receives enablePaimonHms=true whenever kerberos1
does. The fixture's mounts (sql/, paimon_data/, auxlib/) exist on kerberos1
only, so under `set -euo pipefail` kerberos2 would abort at

    hdfs dfs -put -f /opt/doris/paimon_data/* /user/hive/warehouse/

the moment the pipeline turns the switch on, taking down every case that uses
the second realm.

Gate the fixture on the container role (HOST=hadoop-master, set per container
by kerberos*_settings.env) in addition to the switch. Gating on the role
rather than on the mounts keeps a broken mount on kerberos1 failing loudly,
while kerberos2 skips deterministically.

Found while porting this fix to master; the master PR (apache#66433) carries the
same gate.

Signed-off-by: morningman <yunyou@selectdb.com>
@morningman

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17770	4014	3964	3964
q2	2001	333	205	205
q3	10277	1377	858	858
q4	4675	468	337	337
q5	7493	821	552	552
q6	184	166	134	134
q7	726	783	594	594
q8	9338	1526	1429	1429
q9	5180	4032	4001	4001
q10	6744	1607	1393	1393
q11	499	342	331	331
q12	738	576	456	456
q13	18079	3269	2767	2767
q14	263	252	239	239
q15	q16	733	732	660	660
q17	1028	1020	978	978
q18	6580	5610	5608	5608
q19	1301	1285	1072	1072
q20	808	696	581	581
q21	5848	2599	2392	2392
q22	431	359	308	308
Total cold run time: 100696 ms
Total hot run time: 28859 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4255	4179	4148	4148
q2	285	315	207	207
q3	4560	4905	4364	4364
q4	2151	2221	1422	1422
q5	4212	4108	4145	4108
q6	224	169	125	125
q7	1666	1633	1435	1435
q8	2435	2328	2116	2116
q9	7353	7350	7616	7350
q10	4314	4264	3929	3929
q11	548	408	386	386
q12	718	737	517	517
q13	3209	3511	2906	2906
q14	303	315	273	273
q15	q16	686	710	630	630
q17	1319	1269	1252	1252
q18	12109	10976	11737	10976
q19	1151	1105	1168	1105
q20	2245	2247	1942	1942
q21	5623	4837	4850	4837
q22	551	471	429	429
Total cold run time: 59917 ms
Total hot run time: 54457 ms

@hello-stephen

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

query5	4304	587	455	455
query6	445	218	195	195
query7	4853	612	341	341
query8	333	157	160	157
query9	8765	4089	4076	4076
query10	492	347	291	291
query11	5855	2186	1979	1979
query12	157	95	97	95
query13	1279	569	451	451
query14	6083	4240	3932	3932
query14_1	3756	3756	3766	3756
query15	203	198	177	177
query16	968	475	422	422
query17	917	674	540	540
query18	2424	458	341	341
query19	201	182	139	139
query20	106	105	99	99
query21	234	157	134	134
query22	12963	13052	12780	12780
query23	15790	14947	14593	14593
query23_1	15486	15237	15080	15080
query24	7646	1687	1249	1249
query24_1	1234	1257	1243	1243
query25	565	441	386	386
query26	1323	366	210	210
query27	2589	622	367	367
query28	4562	2055	2069	2055
query29	1070	652	486	486
query30	346	266	221	221
query31	1166	1111	1050	1050
query32	109	65	61	61
query33	529	315	241	241
query34	1176	1118	624	624
query35	733	742	633	633
query36	784	780	709	709
query37	153	105	94	94
query38	1831	1761	1678	1678
query39	867	825	792	792
query39_1	774	782	783	782
query40	246	166	149	149
query41	72	66	66	66
query42	93	92	91	91
query43	311	359	279	279
query44	1417	762	765	762
query45	182	170	166	166
query46	1029	1126	718	718
query47	1533	1593	1440	1440
query48	405	413	279	279
query49	576	401	293	293
query50	1070	429	331	331
query51	10593	10804	10219	10219
query52	89	86	75	75
query53	260	272	209	209
query54	277	251	222	222
query55	74	74	64	64
query56	293	289	271	271
query57	1032	1025	944	944
query58	266	271	254	254
query59	1564	1591	1381	1381
query60	307	279	257	257
query61	150	145	149	145
query62	400	319	264	264
query63	228	193	191	191
query64	2866	999	861	861
query65	3869	3834	3810	3810
query66	1836	480	346	346
query67	28131	28113	27895	27895
query68	3132	1548	996	996
query69	416	306	255	255
query70	877	786	791	786
query71	378	365	336	336
query72	2956	2627	2342	2342
query73	833	761	446	446
query74	4608	4485	4288	4288
query75	2367	2324	1971	1971
query76	2336	1154	797	797
query77	347	354	264	264
query78	11217	10939	10555	10555
query79	1388	1127	744	744
query80	1238	552	474	474
query81	548	332	280	280
query82	641	166	150	150
query83	376	333	295	295
query84	326	155	130	130
query85	960	603	511	511
query86	400	235	227	227
query87	2004	1955	1821	1821
query88	3716	2810	2795	2795
query89	384	314	286	286
query90	1938	202	185	185
query91	199	182	162	162
query92	62	60	58	58
query93	1627	1671	1029	1029
query94	705	372	315	315
query95	824	574	467	467
query96	1061	780	350	350
query97	2456	2459	2329	2329
query98	195	184	185	184
query99	750	716	618	618
Total cold run time: 253792 ms
Total hot run time: 166574 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.09	0.06	0.05
query3	0.25	0.14	0.14
query4	1.60	0.14	0.14
query5	0.24	0.22	0.24
query6	1.16	0.82	0.82
query7	0.05	0.01	0.01
query8	0.07	0.04	0.04
query9	0.38	0.32	0.32
query10	0.57	0.60	0.58
query11	0.18	0.13	0.14
query12	0.18	0.14	0.14
query13	0.47	0.47	0.49
query14	1.04	0.99	0.98
query15	0.60	0.58	0.58
query16	0.33	0.32	0.31
query17	1.10	1.05	1.09
query18	0.21	0.20	0.20
query19	2.03	1.96	1.98
query20	0.02	0.01	0.01
query21	15.44	0.21	0.15
query22	4.92	0.05	0.05
query23	16.12	0.32	0.13
query24	2.93	0.42	0.31
query25	0.11	0.06	0.06
query26	0.72	0.21	0.16
query27	0.04	0.04	0.04
query28	3.54	0.78	0.34
query29	12.52	4.04	3.17
query30	0.27	0.15	0.16
query31	2.76	0.55	0.31
query32	3.22	0.58	0.49
query33	3.15	3.14	3.16
query34	15.60	3.90	3.29
query35	3.25	3.22	3.21
query36	0.55	0.43	0.41
query37	0.08	0.07	0.06
query38	0.04	0.04	0.03
query39	0.04	0.03	0.03
query40	0.17	0.15	0.15
query41	0.08	0.03	0.03
query42	0.04	0.03	0.03
query43	0.05	0.03	0.03
Total cold run time: 96.22 s
Total hot run time: 23.93 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 100% (0/0) 🎉
Increment coverage report
Complete coverage report

@morningman
morningman merged commit 0bdb7b6 into apache:master Aug 5, 2026
30 of 31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants