[Bug] BE crashes when retrying duplicate txn commit with a moved-from pending rowset guard
- Dominant language
- Java
- Stars
- 15.9k
- Forks
- 3.9k
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 520
Description
### Search before asking
- [x] I had searched in the [issues](https://github.com/apache/doris/issues?q=is%3Aissue) and found no similar issues.
### Version
Apache Doris master
Tested master revision: 4a11d0b...
### What's Wrong?
A BE can crash when a transaction commit succeeds locally but its response
times out and the caller retries the same commit.
The first commit transfers the `PendingRowsetGuard` into `TabletTxnInfo`.
The retry may therefore carry the same moved-from, uninitialized guard.
The duplicate-commit path previously unconditionally move-assigned the
incoming guard over the initialized guard stored in `TabletTxnInfo`. This
violates the move-assignment invariant of `PendingRowsetGuard` and triggers
a `CHECK`.
### What You Expected?
A duplicate transaction commit caused by an RPC timeout should return success without crashing the BE. The pending rowset state created by the original successful commit should remain valid.
### How to Reproduce?
Add the following BE unit test:
```cpp
TEST_F(TxnManagerTest, ReproduceDuplicateCommitWithMovedFromPendingRowsetGuard) {
auto guard = k_engine->pending_local_rowsets().add(_rowset->rowset_id());
auto st = k_engine->txn_manager()->commit_txn(
_meta.get(), partition_id, transaction_id, tablet_id, _tablet_uid, load_id, _rowset,
std::move(guard), false);
ASSERT_TRUE(st.ok()) << st;
st = k_engine->txn_manager()->commit_txn(
_meta.get(), partition_id, transaction_id, tablet_id, _tablet_uid, load_id,
_rowset_same_id, std::move(guard), false);
ASSERT_TRUE(st.ok()) << st;
}
```
### Anything Else?
_No response_
### Are you willing to submit PR?
- [x] Yes I am willing to submit a PR!
### Code of Conduct
- [x] I agree to follow this project's [Code of Conduct](https://www.apache.org/foundation/policies/conduct)
Contributor guide
Research direction
Start at the BE transaction manager's commit_txn entry point and inspect the duplicate-commit path involving PendingRowsetGuard and TabletTxnInfo. Add the provided TxnManagerTest reproduction, then run the BE unit test to verify that retrying the same commit returns success without crashing and preserves the pending rowset state.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100