Repository navigation
[Bug] INSERT OVERWRITE can drop committed rows: crash, swap failure, and uncertain remote/cloud commits #68679
Description
Activity
Breakwater-GitHub-Analysis-Slot: slot_9c2dc24ef6e2
Initial assessment (read-only source review): high-priority correctness risk for stream-consuming
INSERT OVERWRITE; no production occurrence or remote/cloud fault-injection result is established by this issue. I checkedapache/dorismaster at7d231485588(2026-09-30 08:25 UTC, just before this issue). The issue currently has no labels.Confirmed from code
- The inner insert attaches stream updates to its transaction; the local transaction applies them after committing and on replay (insert setup, commit/replay).
InsertOverwriteTableCommandthen swaps temporary partitions separately and callstaskFailon a swap exception (overwrite sequence); the swap has its own edit-log record (replacement log). On master transfer, outstanding tasks are failed and their temporary partitions are dropped (recovery, cleanup). Thus a committed offset can outlive an unpublished or dropped temporary partition. A swap exception does surface an error for that attempt; the potentially silent loss is on a later read from the advanced offset. - A lost remote commit reply can leave the caller unable to distinguish a committed transaction from a failed one: the RPC has finite retries, and the caller's failure path aborts best-effort while overwrite cleanup can drop the remote temporary partitions (retry, commit/abort). This is a conditional loss window, not proof that the reported remote case has occurred. In particular, the remote commit request does not carry stream updates, so the claimed remote offset impact needs a separate concrete reproduction.
- Cloud commit requests include stream updates (request). The meta-service maps exhausted
KV_TXN_MAYBE_COMMITTEDretries toKV_TXN_COMMIT_ERR(retry boundary); FE treats that response as an error (FE response handling). Whether any particular transaction actually committed remains unknown until checked at the owner.
Important scope correction: current master already journals an IVM partition rebuild requirement before that refresh reads (MTMV task). The checked-in failure-between-halves regression expects the following refresh to rebuild the partition and recover the row. That limits the stated IVM impact on this master revision; it does not close the direct stream-overwrite gap. PR #68662 is open, so its cancellation changes should not yet be assumed present on master. The remote lock-wait cancellation/success scenario also needs its own deterministic test.
Requested evidence / next steps: Please provide an exact build SHA and mode (local, remote, or cloud), minimal table/stream SQL and partition layout, transaction ID, overwrite task ID, affected partition IDs, stream offset before/after, and row counts before/after retry. For failover, include FE edit-log ordering and leader-transition logs; for remote, caller/owner FE commit and abort RPC logs plus owner transaction status; for cloud, meta-service commit response/
actual_codeand authoritative transaction status. A direct stream-overwrite fault-injection test at commit-before-swap, plus lost-reply and maybe-committed tests, would establish the remaining outcomes. The fix should make publication recoverable with the committed consumption decision, and reconcile uncertain commits with the owning FE/meta-service before any temporary-partition cleanup; a local error alone cannot determine whether rollback is safe.- The inner insert attaches stream updates to its transaction; the local transaction applies them after committing and on replay (insert setup, commit/replay).
- added a commit that references this issue
on Oct 10, 2026
Search before asking
Version
master (the two-phase overwrite in
InsertOverwriteTableCommandand its publication viaReplacePartitionOperationLog, and the remote/cloud commit paths as of 2026-09).What's Wrong?
An
INSERT OVERWRITEis two-phase: the rows are committed into temporary partitions first (InsertIntoTableCommandhangs the table stream offsets on that transaction;DatabaseTransactionMgr.updateCatalogAfterCommittedapplies them on commit and replays them), and a later swap publishes them (Env.replaceTempPartition/ReplacePartitionOperationLog). Two durable facts are therefore split across two journal records, and three remaining paths can leave the offset (and the rows) advanced while nothing is published, with no error:Env.transferToMastercallsInsertOverwriteManager.allTaskFail()and drops every in-flight task's temporary partitions) or the swap itself fails (replacePartitionthrowing). The committed rows are gone and the consumed offset stays advanced, so a re-run reads from the advanced position and that range is missing.RemoteOlapInsertExecutor.onCompletecommits on the owning FE and then waits; ifmasterCallWithRetryexhausts its retries after the owner committed, this FE sees an error,onFail's abort cannot take a committed remote transaction back, and the overwrite rolls the temporary partitions back, dropping rows that exist.KV_TXN_COMMIT_ERRandcommitAndPublishTransactionWithRetrythrows, so the overwrite rolls back temporary partitions whose rows and stream offsets the meta service may already hold.The same shape shows up where the decision is the owning FE's: for a remote target, a cancellation that arrives while
replacePartitionsImplwaits for the table write lock is not conveyed by the replacement RPC, so an overwrite whose insert committed nothing can still publish an empty result and report success. (The local equivalents of the cancellation cases, and the local error-response case, are fixed by #68662.)Impact: silent partial data for
INSERT OVERWRITE t SELECT * FROM stream(...), and for an IVM/MTMV partition refresh, which resets the stream offsets of exactly the partitions it replaces -- the partition keeps its old rows, the change it read is consumed, and the following refresh reports success. Trace issue for the IVM side: #65418.What You Expected?
Once a load's rows (or stream offsets) are committed, the overwrite must publish them:
committedandpublishedmust not be able to disagree, whatever happens to the FE, the RPC or the meta service in between. Where the commit outcome is genuinely unknown, the overwrite must not answer with a rollback that can drop durable rows.How to Reproduce?
INSERT OVERWRITE t SELECT * FROM stream('db', 'src')(or an IVM partition refresh) and stop the FE (or inject a failure in the swap) between the insert's commit and the swap; the temporary partitions are dropped byallTaskFail/taskFailwhile the offsets stay advanced.masterCallWithRetryexhausting retries) after the owning FE committed; the temporary partitions are rolled back on this side.KV_TXN_COMMIT_ERR).The local cancellation and publication-timeout variants are pinned by the regression suite added in #68662 (
insert_overwrite_p0/test_insert_overwrite_cancel), and the localreplacePartition-failure and crash windows are pinned bymtmv_p0/ivm/test_ivm_overwrite_failure_between_the_halves.Anything Else?
Fix directions, in increasing order of cost:
TransactionState; a "committed catalog action" for the partition swap would ride the same record, and the publish/finish path already re-drives committed transactions after a restart).ReplacePartitionOperationLog), which keeps the transaction path untouched but weakens the read-range exclusivitycheckStreamOffsetprovides during the window, and needs a separate answer for cloud read state.allTaskFaildrops anyway.Are you willing to submit PR?
Code of Conduct