Eraj Saliev
07/29/2026, 2:01 AMRocky
07/29/2026, 2:02 AMmerge_condition, Delete Vectors (DelVectors), and the late materialization optimization.
In StarRocks Primary Key tables, queries with predicates often use "late materialization," where the filter column is read first to identify matching row IDs. If there is a discrepancy between the projection and the predicate, it typically means the underlying DelVector or the Persistent Index mapping has become inconsistent, causing the scanner to "see" different versions of the row depending on the access path.
1. Analysis of the Bug
Your repro demonstrates a Projection vs. Predicate mismatch:
* Case A (Projection): A full scan (or projection-led scan) correctly identifies that for pk_col = 'ROW_X', the value of col_a is 'VALUE_X'.
* Case B (Predicate): A filtered scan for col_a = 'VALUE_X' fails to find the same row.
Since you ruled out indexing (Bloom Filter/Zonemaps) via CONCAT, the issue lies in the row visibility logic at the scan layer. The most likely culprit is Issue #72542: _"merge_condition was not preserved when applying a normal rowset commit."_ In StarRocks 4.1.1 (and some 4.0.x versions), a bug was identified where the merge_condition logic could be bypassed during specific commit or compaction sequences, leading to:
1. Older row versions not being correctly marked as deleted in the DelVector.
2. The Persistent Index pointing to a "stale" location for a PK while the data file contains the "new" value.
3. Inconsistent visibility where a predicate (which might hit an older segment/rowset first) decides a row doesn't match before the "latest" version is even considered.
2. Answers to Your Questions
* 1. Can a non-key predicate evaluate against a different row generation?
Yes. In the PK engine, if the DelVector is inconsistent, a query scanning for a predicate might evaluate an older, "ghost" version of a row that should have been deleted. If that older version doesn't match the predicate, the engine moves on, potentially never reaching the "latest" version if the short-circuiting logic or late materialization is triggered incorrectly.
* 2. Any supported repair short of rewriting partitions?
If COMPACT (Full Compaction) does not fix it, it means the metadata (the DelVectors or the mapping in the Persistent Index) is structurally incorrect based on the rowsets' history.
* Attempt `ADMIN CHECK TABLET`: Run ADMIN CHECK TABLET (tablet_id) on the affected tablet to see if StarRocks detects internal checksum or version mismatches.
* Rewrite is required: Currently, the only reliable way to "heal" the state is to force a re-calculation of the primary key mapping by rewriting the partition:
sql
INSERT OVERWRITE fact_table PARTITION (p20260624) SELECT * FROM fact_table PARTITION (p20260624);
* 3. Is there a way to detect affected rows?
There is no built-in "consistency check" that automatically finds these mismatches. You can detect them by running a "mismatch query" that looks for rows that exist in a projection but disappear in a predicate:
sql
-- Example detection query
SELECT pk_col FROM db.fact_table
WHERE part_ts = '2026-06-24'
GROUP BY pk_col
HAVING MAX(col_a) = 'VALUE_X'
AND pk_col NOT IN (SELECT pk_col FROM db.fact_table WHERE col_a = 'VALUE_X');
* 4. Is enable_persistent_index implicated?
Indirectly, yes. The persistent index manages the PK-to-RowID mapping. If the index update failed or was partially applied (common in older 4.x/3.x edge cases involving merge_condition), the DelVector generated for new rowsets will be wrong. However, disabling it at 2B rows would likely cause OOM and is not recommended as a "fix."
* 5. Known and fixed in a later 4.1.x?Rocky
07/29/2026, 2:02 AMmerge_condition and DelVector orphan bugs (#72542, #71049, #72350) has been addressed in StarRocks 4.1.2+ and 4.1.3.
Recommendation
1. Upgrade immediately to the latest 4.1.x patch (at least 4.1.3) to prevent new occurrences.
2. Identify and Rewrite: Use a script to run the detection query above on suspicious partitions. Use INSERT OVERWRITE to fix those partitions.
3. Validate: After upgrading and rewriting, run a FULL COMPACTION on the affected tablets to ensure all "ghost" rowsets are physically purged.
References
• table_design/table_types/primary_key_table.md
• best_practices/primarykey_table.mdEraj Saliev
07/29/2026, 2:49 AMRocky
07/29/2026, 2:50 AMmerge_condition), the community is targeting the next immediate patches (4.1.2 and 4.1.3) to verify the fix across both shared-nothing and shared-data architectures.
Recommendation
* Track the PR: You can follow the progress of the fix directly on GitHub at Issue #72542. Once that PR is merged into the branch-4.1, it will be included in the very next patch release.
* Workaround: Until the patch is available, continue using the INSERT OVERWRITE method for affected partitions. This forces a physical rewrite and re-indexing of the data, which bypasses the metadata inconsistency in the current rowset chain.
* Check the Download Page: Keep an eye on the official download page. Patch notes are usually uploaded within 24 hours of the binary being tagged on GitHub.
If you have a critical production blocker, I recommend reaching out on the StarRocks Slack in the #support channel or opening a priority issue on GitHub referencing your repro and #72542.
References
• release_notes/release-4.0.md