Skip to content

[fix](ivm) Invalidate the baseline when a column used by the MV is dropped - #67837

Merged
yujun777 merged 4 commits into
apache:masterfrom
yujun777:ivm-drop-column-baseline-rebuild
Sep 11, 2026
Merged

[fix](ivm) Invalidate the baseline when a column used by the MV is dropped#67837
yujun777 merged 4 commits into
apache:masterfrom
yujun777:ivm-drop-column-baseline-rebuild

Conversation

@yujun777

@yujun777 yujun777 commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Trace issue: #65418

Problem Summary:

A light schema change on an IVM base table (DROP COLUMN, usually followed by an ADD COLUMN with the same name) only changes metadata and emits no row binlog. When the dropped column is one the MV uses, the next REFRESH ... INCREMENTAL consumes an empty delta and reports SUCCESS, while the MV silently keeps the rows that were computed under the old column.

Dropping the column did reach the MTMV hook, but that only moved the MV status to SCHEMA_CHANGE. That state merely re-analyses the MV query on the next refresh - and by then the column is usually back under the same name, so the analysis succeeds and the incremental refresh proceeds. The IVM baseline barrier (requireCompleteBaselineRebuild) was never raised on this path: it is only set for REPLACE TABLE, REPLACE PARTITION and partition changes.

What this PR does

Re-analyse the MV query on the alterTable path, right after the alter was applied, and invalidate the IVM baseline when the query no longer binds.

This needs no lineage machinery: dropping or renaming a column the MV uses makes the query unanalysable, so the failure itself is the dependency signal - and dropping a column the MV does not reference leaves the incremental path untouched.

Scope: on an IVM base table only DROP COLUMN and RENAME TABLE can change a referenced column at all (row binlog tables reject MODIFY COLUMN, RENAME COLUMN and REORDER COLUMNS), so those two operations are the whole surface. A dropped base table needs no handling - the IVM stream records the base table id and stops being usable, which already fails the refresh.

The analysis runs in a context of its own rather than the session that issued the alter, because the underlying analyzeQueryWithSql reuses and closes the statement context it is handed.

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
  • Behavior changed:

    • Yes. Dropping or renaming a column an IVM references now marks the IVM baseline as needing a rebuild, so a strict REFRESH ... INCREMENTAL is rejected with IVM baseline rebuild is pending ... run an AUTO or COMPLETE refresh first instead of silently reporting SUCCESS. Dropping a column the MV does not use is unaffected.
  • Does this need documentation?

    • No.

…opped

A light schema change only touches metadata and emits no row binlog. When a column
the MV uses is dropped - and typically re-added under the same name right after - the
incremental refresh therefore consumes an empty delta and reports SUCCESS while the MV
keeps the rows computed under the old column, so the staleness is silent.

The change did reach the MTMV hook, but that only moved the MV status to SCHEMA_CHANGE,
which merely re-analyses the MV query on the next refresh. By then the column is back
under the same name, so the analysis succeeds again and nothing blocks the incremental
path. The IVM baseline barrier was never raised here: it is only set for REPLACE TABLE,
REPLACE PARTITION and partition changes.

Re-analyse the MV query on the alterTable path, right after the alter was applied, and
invalidate the baseline when the query no longer binds. Dropping or renaming a column the
MV uses makes the query unanalysable, so this doubles as the dependency check: dropping a
column the MV does not reference leaves the incremental path untouched.

On an IVM base table only DROP COLUMN and RENAME TABLE can change a referenced column at
all (row binlog tables reject MODIFY COLUMN, RENAME COLUMN and REORDER COLUMNS), so those
two operations are the whole scope. A dropped base table needs no handling - the IVM
stream records the base table id and stops being usable, which already fails the refresh.

The check analyses with a context of its own rather than the one that issued the alter,
because the analysis reuses and closes the statement context it is handed.
@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?

@yujun777

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 78.95% (15/19) 🎉
Increment coverage report
Complete coverage report

Renaming an IVM base table invalidated the IVM baseline: the query-usability probe cannot
succeed after a rename, because the MV query still spells the old table name. That
invalidation is invisible to the user -- the refresh resolves its base tables from the query
before it ever checks the baseline, so it reports the missing table either way -- but the
flag it sets is durable: renaming the table back left every strict INCREMENTAL refresh
rejected until a COMPLETE one had been run.

Key changes:
- Skip the query-usability probe when the alter is a rename, detected by the base table name
  changing. Only RenameTableOp and ReplaceTableOp fill newBaseTableInfo
  (Alter#processAlterTable), and ReplaceTableOp keeps its isReplace branch, so every other op
  still probes and a dropped referenced column is still caught.

Unit Test
- IvmBaselineRebuildTest#testRenameTableBackKeepsIncrementalRefreshStartable (new)
- IvmBaselineRebuildTest#testRenameTableDoesNotMarkBaselineRebuild
- IvmBaselineRebuildTest (whole class)
@yujun777

Copy link
Copy Markdown
Contributor Author

run buildall

…on cloud

The suite creates its own tables and reads back only its own task status, so it does not
touch cluster-wide state: declaring nonConcurrent takes it out of the parallel pool and
slows the whole run down for nothing. The cloud guard came in with the older IVM suites
without a stated reason, and both cases this suite covers were reported from a cloud
deployment, so skipping cloud hid exactly the regression it exists to catch.

Key changes:
- Drop the nonConcurrent group and the isCloudMode early return from
  test_ivm_drop_referenced_column_baseline_rebuild, leaving the suite body unchanged.

Unit Test
- Not run locally: only the suite group and the cloud guard were removed.
@yujun777

Copy link
Copy Markdown
Contributor Author

run buildall

…golden file

The suite compared SQL result sets with assertEquals on List.toString(), which hides the diff
when a query breaks and ties the assertion to the list formatting. Both queries now go through
order_qt_* and their expected rows live in the suite's .out file.

Key changes:
- Replace the two mvRows assertEquals checks with order_qt_mv_rows_baseline and
  order_qt_mv_rows_after_aba, and drop the now unused mvRows closure.
- Add regression-test/data/mtmv_p0/ivm/test_ivm_drop_referenced_column_baseline_rebuild.out.

Unit Test
- test_ivm_drop_referenced_column_baseline_rebuild: run with -forceGenOut to produce the golden
  file, then again without it to confirm the comparisons hold.
@yujun777

Copy link
Copy Markdown
Contributor Author

run buildall

@yujun777

Copy link
Copy Markdown
Contributor Author

run feut

@yujun777

Copy link
Copy Markdown
Contributor Author

run vault_p0

@yujun777

Copy link
Copy Markdown
Contributor Author

run external

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17573	3081	3051	3051
q2	2053	248	232	232
q3	10276	890	517	517
q4	4671	252	201	201
q5	7671	581	393	393
q6	135	112	100	100
q7	544	506	384	384
q8	9235	879	863	863
q9	3466	2435	2430	2430
q10	6497	897	719	719
q11	392	197	182	182
q12	606	260	199	199
q13	18144	1544	1157	1157
q14	158	152	145	145
q15	q16	435	399	374	374
q17	1297	867	789	789
q18	3105	2294	2250	2250
q19	1275	919	742	742
q20	392	286	210	210
q21	5680	1684	1851	1684
q22	333	273	227	227
Total cold run time: 93938 ms
Total hot run time: 16849 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3436	3384	3357	3357
q2	508	409	382	382
q3	2262	2380	2295	2295
q4	1213	1185	904	904
q5	2256	2174	2151	2151
q6	177	120	89	89
q7	1052	911	956	911
q8	1621	1429	1416	1416
q9	3210	3172	3178	3172
q10	1913	1883	1685	1685
q11	359	271	254	254
q12	461	448	344	344
q13	1504	1556	1171	1171
q14	180	171	160	160
q15	q16	409	399	365	365
q17	3638	3379	3266	3266
q18	4952	4499	4952	4499
q19	949	852	860	852
q20	1018	952	837	837
q21	3871	3186	3204	3186
q22	415	363	322	322
Total cold run time: 35404 ms
Total hot run time: 31618 ms

@hello-stephen

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

query5	4259	418	337	337
query6	400	133	129	129
query7	4928	426	232	232
query8	289	128	118	118
query9	8690	2905	2898	2898
query10	412	210	181	181
query11	5371	1071	915	915
query12	127	69	71	69
query13	1191	462	318	318
query14	6017	2241	2125	2125
query14_1	1998	1995	1999	1995
query15	168	116	121	116
query16	932	371	366	366
query17	778	438	344	344
query18	2322	311	231	231
query19	163	135	104	104
query20	72	72	70	70
query21	196	112	86	86
query22	5537	5414	5512	5414
query23	6845	6362	6197	6197
query23_1	6285	6331	6426	6331
query24	7321	1106	789	789
query24_1	797	796	768	768
query25	399	283	252	252
query26	1231	232	132	132
query27	2786	396	260	260
query28	4700	1501	1525	1501
query29	899	423	339	339
query30	255	159	133	133
query31	815	404	333	333
query32	132	78	79	78
query33	452	218	173	173
query34	1004	838	492	492
query35	429	400	343	343
query36	576	547	525	525
query37	117	77	67	67
query38	1000	855	843	843
query39	479	483	511	483
query39_1	456	472	484	472
query40	200	91	75	75
query41	57	52	50	50
query42	73	71	82	71
query43	249	242	214	214
query44	989	543	549	543
query45	110	118	103	103
query46	758	877	532	532
query47	763	793	714	714
query48	301	303	226	226
query49	549	243	195	195
query50	804	269	199	199
query51	8223	8224	8226	8224
query52	74	68	61	61
query53	194	220	168	168
query54	262	186	152	152
query55	77	62	60	60
query56	208	193	176	176
query57	699	665	667	665
query58	196	183	177	177
query59	1229	1266	1094	1094
query60	238	184	192	184
query61	131	131	124	124
query62	370	205	178	178
query63	175	143	148	143
query64	2901	784	670	670
query65	1658	1658	1607	1607
query66	1767	270	212	212
query67	10335	10151	10014	10014
query68	3032	1218	717	717
query69	360	228	206	206
query70	679	618	637	618
query71	253	186	157	157
query72	2294	1752	1539	1539
query73	657	575	347	347
query74	2015	1245	1182	1182
query75	1194	1127	968	968
query76	2379	710	527	527
query77	260	267	217	217
query78	4102	3792	3230	3230
query79	2752	802	610	610
query80	1585	323	263	263
query81	520	158	135	135
query82	745	140	96	96
query83	279	213	194	194
query84	300	111	89	89
query85	837	347	279	279
query86	467	172	165	165
query87	1034	992	913	913
query88	3050	2104	2113	2104
query89	278	196	180	180
query90	2106	125	133	125
query91	145	119	97	97
query92	98	75	70	70
query93	2132	1139	752	752
query94	635	240	224	224
query95	520	250	313	250
query96	840	575	266	266
query97	1127	1071	1021	1021
query98	179	140	135	135
query99	430	346	314	314
Total cold run time: 181132 ms
Total hot run time: 83554 ms

@hello-stephen

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

query1	0.00	0.01	0.00
query2	0.07	0.03	0.03
query3	0.24	0.11	0.11
query4	1.60	0.10	0.10
query5	0.17	0.16	0.17
query6	1.24	0.70	0.70
query7	0.03	0.01	0.00
query8	0.04	0.03	0.03
query9	0.28	0.22	0.22
query10	0.35	0.34	0.35
query11	0.16	0.12	0.11
query12	0.15	0.12	0.11
query13	0.31	0.31	0.32
query14	0.48	0.46	0.46
query15	0.37	0.35	0.35
query16	0.21	0.24	0.23
query17	0.70	0.70	0.73
query18	0.18	0.17	0.18
query19	1.22	1.19	1.20
query20	0.01	0.00	0.00
query21	15.45	0.16	0.12
query22	5.07	0.05	0.04
query23	16.17	0.26	0.10
query24	3.01	0.34	0.26
query25	0.10	0.04	0.04
query26	0.73	0.16	0.11
query27	0.04	0.03	0.03
query28	3.79	0.58	0.28
query29	12.45	3.27	2.57
query30	0.26	0.12	0.13
query31	2.75	0.38	0.17
query32	3.51	0.32	0.23
query33	1.46	1.46	1.44
query34	15.34	2.23	1.79
query35	1.74	1.77	1.78
query36	0.45	0.30	0.29
query37	0.06	0.04	0.04
query38	0.04	0.03	0.02
query39	0.03	0.03	0.02
query40	0.12	0.08	0.08
query41	0.08	0.02	0.02
query42	0.15	0.02	0.02
query43	0.04	0.03	0.02
Total cold run time: 90.65 s
Total hot run time: 14.9 s

@yujun777
yujun777 merged commit 3050a9a into apache:master Sep 11, 2026
34 of 36 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.

4 participants