[
https://issues.apache.org/jira/browse/KAFKA-9777?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Jason Gustafson resolved KAFKA-9777.
------------------------------------
Fix Version/s: 2.6.0
Resolution: Fixed
> Purgatory locking bug can lead to hanging transaction
> -----------------------------------------------------
>
> Key: KAFKA-9777
> URL: https://issues.apache.org/jira/browse/KAFKA-9777
> Project: Kafka
> Issue Type: Bug
> Affects Versions: 1.1.1, 2.0.1, 2.1.1, 2.2.2, 2.3.1, 2.4.1
> Reporter: Jason Gustafson
> Assignee: Jason Gustafson
> Priority: Critical
> Fix For: 2.6.0
>
>
> Once a transaction reaches the `PrepareCommit` or `PrepareAbort` state, the
> transaction coordinator must send markers to all partitions included in the
> transaction. After all markers have been sent, then the transaction
> transitions to the corresponding completed state. Until this transition
> occurs, no additional progress can be made by the producer.
> The transaction coordinator uses a purgatory to track completion of the
> markers that need to be sent. Once all markers have been written, then the
> `DelayedTxnMarker` task becomes completable. We depend on its completion in
> order to transition to the completed state.
> Related to KAFKA-8334, there is a bug in the locking protocol which is used
> to check completion of the `DelayedTxnMarker` task. The purgatory attempts to
> provide a "happens before" contract for task completion with
> `checkAndComplete`. Basically if a task is completed before calling
> `checkAndComplete`, then it should be given an opportunity to complete as
> long as there is sufficient time remaining before expiration.
> The bug in the locking protocol is that it expects that the operation lock is
> exclusive to the operation. See here:
> https://github.com/apache/kafka/blob/trunk/core/src/main/scala/kafka/server/DelayedOperation.scala#L114.
> The logic assumes that if the lock cannot be acquired, then the other holder
> of the lock must be attempting completion of the same delayed operation. If
> that is not the case, then the "happens before" contract is broken and a task
> may not get completed until expiration even if it has been satisfied.
> In the case of `DelayedTxnMarker`, the lock in use is the read side of a
> read-write lock which is used for partition loading:
> https://github.com/apache/kafka/blob/trunk/core/src/main/scala/kafka/coordinator/transaction/TransactionMarkerChannelManager.scala#L264.
> In fact, if the lock cannot be acquired, it means that it is being held in
> order to complete some loading operation, in which case it will definitely
> not attempt completion of the delayed operation. If this happens to occur on
> the last call to `checkAndComplete` after all markers have been written, then
> the transition to the completing state will never occur.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)