Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rangefeed: don't discard ref count for txn after intent abort #35777

Merged
merged 1 commit into from
Mar 15, 2019

Conversation

nvanbenschoten
Copy link
Member

Fixes #34600.

Before this commit, rangefeed made the assumption that an aborted intent
implied an aborted transaction (after the rangefeed was in a steady-state).
It used this assumption to eagerly discard the bookkeeping for a transaction
after its first MVCCAbortIntent operation was seen as an optimization.

This was incorrect. A transaction can "abort" an intent even if it commits.
This is possible if the intent was only written at a previous epoch and not
written in the epoch that ended up finalizing the transaction. This commit
removes this assumption, which I confirmed fixes the resolved timestamp
regression using the new assertion from #35772.

I believe this could have two effects:

  • it could trigger the assertion failure from roachtest: cdc/crdb-chaos/rangefeed=true failed #34600 if the transaction
    experiencing the incorrect assumption was the oldest being tracked at
    the time of the assumption.
  • it could cause resolved timestamp stalls and prevent all future forward
    progress of resolved timestamps if the transaction experiencing the incorrect
    assumption was not the oldest being tracked at the time of the assumption.

Release note: None

@nvanbenschoten nvanbenschoten requested review from danhhz and a team March 15, 2019 04:30
@cockroach-teamcity
Copy link
Member

This change is Reviewable

Copy link
Member

@tbg tbg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Reviewed 2 of 2 files at r1.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @danhhz)

Copy link
Contributor

@danhhz danhhz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great find! I'm curious, any theories why this would have become more frequent recently?

@nvanbenschoten
Copy link
Member Author

I'm curious, any theories why this would have become more frequent recently?

An increase in transaction retries is the only thing I can think of. #34600 was failing so reliably for other reasons though. Do you think it is safe to say that this became more frequent recently or was it just hidden?

bors r+

@craig
Copy link
Contributor

craig bot commented Mar 15, 2019

Merge conflict (retrying...)

@craig
Copy link
Contributor

craig bot commented Mar 15, 2019

Build failed

@nvanbenschoten
Copy link
Member Author

Flake due to #34081.

bors r+

@craig
Copy link
Contributor

craig bot commented Mar 15, 2019

Merge conflict (retrying...)

@craig
Copy link
Contributor

craig bot commented Mar 15, 2019

Build failed

@nvanbenschoten
Copy link
Member Author

Flaked due to #35484.

bors r+

@craig
Copy link
Contributor

craig bot commented Mar 15, 2019

Build failed

Fixes cockroachdb#34600.

Before this commit, rangefeed made the assumption that an aborted intent
implied an aborted transaction (after the rangefeed was in a steady-state).
It used this assumption to eagerly discard the bookkeeping for a transaction
after its first MVCCAbortIntent operation was seen as an optimization.

This was incorrect. A transaction can "abort" an intent even if it commits.
This is possible if the intent was only written at a previous epoch and not
written in the epoch that ended up finalizing the transaction. This commit
removes this assumption, which I confirmed fixes the resolved timestamp
regression using the new assertion from cockroachdb#35772.

I believe this could have two effects:
- it could trigger the assertion failure from cockroachdb#34600 if the transaction
  experiencing the incorrect assumption was the oldest being tracked at
  the time of the assumption.
- it could cause resolved timestamp stalls and prevent all future forward
  progress of resolved timestamps if the transaction experiencing the incorrect
  assumption was not the oldest being tracked at the time of the assumption.

Release note: None
@nvanbenschoten nvanbenschoten force-pushed the nvanbenschoten/fixResTS branch from 48e8d05 to f19dd96 Compare March 15, 2019 21:42
@nvanbenschoten
Copy link
Member Author

Same issue. I'm debugging now in #35549.

bors r+

craig bot pushed a commit that referenced this pull request Mar 15, 2019
35777: rangefeed: don't discard ref count for txn after intent abort r=nvanbenschoten a=nvanbenschoten

Fixes #34600.

Before this commit, rangefeed made the assumption that an aborted intent
implied an aborted transaction (after the rangefeed was in a steady-state).
It used this assumption to eagerly discard the bookkeeping for a transaction
after its first MVCCAbortIntent operation was seen as an optimization.

This was incorrect. A transaction can "abort" an intent even if it commits.
This is possible if the intent was only written at a previous epoch and not
written in the epoch that ended up finalizing the transaction. This commit
removes this assumption, which I confirmed fixes the resolved timestamp
regression using the new assertion from #35772.

I believe this could have two effects:
- it could trigger the assertion failure from #34600 if the transaction
  experiencing the incorrect assumption was the oldest being tracked at
  the time of the assumption.
- it could cause resolved timestamp stalls and prevent all future forward
  progress of resolved timestamps if the transaction experiencing the incorrect
  assumption was not the oldest being tracked at the time of the assumption.

Release note: None

Co-authored-by: Nathan VanBenschoten <[email protected]>
@craig
Copy link
Contributor

craig bot commented Mar 15, 2019

Build succeeded

@craig craig bot merged commit f19dd96 into cockroachdb:master Mar 15, 2019
nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this pull request Mar 18, 2019
Fixes cockroachdb#35816.

The fix in cockroachdb#35777 inadvertently broke `txnPushAttempt` and its interaction with
transactions that were found to be aborted. This commit restores this handling
by reverting part of the assertion added in cockroachdb#35772 and splitting up the handling
of "aborted intents" from the handling of "aborted transactions".

Aborted transactions were always one of the most tricky situations to handle in
rangefeed. The challenge is that rangefeed may be tracking a transaction that
has been abandoned and may want to push it to unblock its resolved timestamp,
but it doesn't have a way to know where the aborted transaction's intents live
on its range. The aborted transaction record can't tell us this either. So the
only thing rangefeed can do is push the transaction and convince itself that the
aborted intents on its range can be safely ignored. This poses a problem for
accurate reference counting of intents though. We need to be able to discard a
transaction and still handle the eventual resolution of its aborted intents.

To handle this properly, the change splits up `MVCCAbortIntentOp` into
`MVCCAbortIntentOp` and `MVCCAbortTxnOp`. Before this change, the single
operation type was attempting to fill both roles, but they mean fundamentally
different things. `MVCCAbortTxnOp` is then given back its ability to delete
transactions from the queue directly without worrying about their reference
count. Next, the `unresolvedIntentQueue` is extended to be a little more
flexible. Instead of asserting that reference counts never drop below zero, it just
ignores changes that would make reference counts negative. This has the potential
to "leak" reference counts that saturate at zero and are then incremented again,
but we know that this will only ever happen for aborted transactions, which can
always be pushed again to rediscover that they have been aborted.

Release note: None
nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this pull request Mar 19, 2019
Fixes cockroachdb#35816.

The fix in cockroachdb#35777 inadvertently broke `txnPushAttempt` and its interaction with
transactions that were found to be aborted. This commit restores this handling
by reverting part of the assertion added in cockroachdb#35772 and splitting up the handling
of "aborted intents" from the handling of "aborted transactions".

Aborted transactions were always one of the most tricky situations to handle in
rangefeed. The challenge is that rangefeed may be tracking a transaction that
has been abandoned and may want to push it to unblock its resolved timestamp,
but it doesn't have a way to know where the aborted transaction's intents live
on its range. The aborted transaction record can't tell us this either. So the
only thing rangefeed can do is push the transaction and convince itself that the
aborted intents on its range can be safely ignored. This poses a problem for
accurate reference counting of intents though. We need to be able to discard a
transaction and still handle the eventual resolution of its aborted intents.

To handle this properly, the change splits up `MVCCAbortIntentOp` into
`MVCCAbortIntentOp` and `MVCCAbortTxnOp`. Before this change, the single
operation type was attempting to fill both roles, but they mean fundamentally
different things. `MVCCAbortTxnOp` is then given back its ability to delete
transactions from the queue directly without worrying about their reference
count. Next, the `unresolvedIntentQueue` is extended to be a little more
flexible. Instead of asserting that reference counts never drop below zero, it just
ignores changes that would make reference counts negative. This has the potential
to "leak" reference counts that saturate at zero and are then incremented again,
but we know that this will only ever happen for aborted transactions, which can
always be pushed again to rediscover that they have been aborted.

Release note: None
nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this pull request Mar 19, 2019
Fixes cockroachdb#35816.

The fix in cockroachdb#35777 inadvertently broke `txnPushAttempt` and its interaction with
transactions that were found to be aborted. This commit restores this handling
by reverting part of the assertion added in cockroachdb#35772 and splitting up the handling
of "aborted intents" from the handling of "aborted transactions".

Aborted transactions were always one of the most tricky situations to handle in
rangefeed. The challenge is that rangefeed may be tracking a transaction that
has been abandoned and may want to push it to unblock its resolved timestamp,
but it doesn't have a way to know where the aborted transaction's intents live
on its range. The aborted transaction record can't tell us this either. So the
only thing rangefeed can do is push the transaction and convince itself that the
aborted intents on its range can be safely ignored. This poses a problem for
accurate reference counting of intents though. We need to be able to discard a
transaction and still handle the eventual resolution of its aborted intents.

To handle this properly, the change splits up `MVCCAbortIntentOp` into
`MVCCAbortIntentOp` and `MVCCAbortTxnOp`. Before this change, the single
operation type was attempting to fill both roles, but they mean fundamentally
different things. `MVCCAbortTxnOp` is then given back its ability to delete
transactions from the queue directly without worrying about their reference
count. Next, the `unresolvedIntentQueue` is extended to be a little more
flexible. Instead of asserting that reference counts never drop below zero, it just
ignores changes that would make reference counts negative. This has the potential
to "leak" reference counts that saturate at zero and are then incremented again,
but we know that this will only ever happen for aborted transactions, which can
always be pushed again to rediscover that they have been aborted.

Release note: None
craig bot pushed a commit that referenced this pull request Mar 19, 2019
35889: rangefeed: fix handling of aborted transactions found by txnPushAttempt r=nvanbenschoten a=nvanbenschoten

Fixes #35816.

The fix in #35777 inadvertently broke `txnPushAttempt` and its interaction with
transactions that were found to be aborted. This commit restores this handling
by reverting part of the assertion added in #35772 and splitting up the handling
of "aborted intents" from the handling of "aborted transactions".

Aborted transactions were always one of the most tricky situations to handle in
rangefeed. The challenge is that rangefeed may be tracking a transaction that
has been abandoned and may want to push it to unblock its resolved timestamp,
but it doesn't have a way to know where the aborted transaction's intents live
on its range. The aborted transaction record can't tell us this either. So the
only thing rangefeed can do is push the transaction and convince itself that the
aborted intents on its range can be safely ignored. This poses a problem for
accurate reference counting of intents though. We need to be able to discard a
transaction and still handle the eventual resolution of its aborted intents.

To handle this properly, the change splits up `MVCCAbortIntentOp` into
`MVCCAbortIntentOp` and `MVCCAbortTxnOp`. Before this change, the single
operation type was attempting to fill both roles, but they mean fundamentally
different things. `MVCCAbortTxnOp` is then given back its ability to delete
transactions from the queue directly without worrying about their reference
count. Next, the `unresolvedIntentQueue` is extended to be a little more
flexible. Instead of asserting that reference counts never drop below zero, it just
ignores changes that would make reference counts negative. This has the potential
to "leak" reference counts that saturate at zero and are then incremented again,
but we know that this will only ever happen for aborted transactions, which can
always be pushed again to rediscover that they have been aborted.

Release note: None

Co-authored-by: Nathan VanBenschoten <[email protected]>
nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this pull request Mar 21, 2019
Fixes cockroachdb#35816.

The fix in cockroachdb#35777 inadvertently broke `txnPushAttempt` and its interaction with
transactions that were found to be aborted. This commit restores this handling
by reverting part of the assertion added in cockroachdb#35772 and splitting up the handling
of "aborted intents" from the handling of "aborted transactions".

Aborted transactions were always one of the most tricky situations to handle in
rangefeed. The challenge is that rangefeed may be tracking a transaction that
has been abandoned and may want to push it to unblock its resolved timestamp,
but it doesn't have a way to know where the aborted transaction's intents live
on its range. The aborted transaction record can't tell us this either. So the
only thing rangefeed can do is push the transaction and convince itself that the
aborted intents on its range can be safely ignored. This poses a problem for
accurate reference counting of intents though. We need to be able to discard a
transaction and still handle the eventual resolution of its aborted intents.

To handle this properly, the change splits up `MVCCAbortIntentOp` into
`MVCCAbortIntentOp` and `MVCCAbortTxnOp`. Before this change, the single
operation type was attempting to fill both roles, but they mean fundamentally
different things. `MVCCAbortTxnOp` is then given back its ability to delete
transactions from the queue directly without worrying about their reference
count. Next, the `unresolvedIntentQueue` is extended to be a little more
flexible. Instead of asserting that reference counts never drop below zero, it just
ignores changes that would make reference counts negative. This has the potential
to "leak" reference counts that saturate at zero and are then incremented again,
but we know that this will only ever happen for aborted transactions, which can
always be pushed again to rediscover that they have been aborted.

Release note: None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

roachtest: cdc/crdb-chaos/rangefeed=true failed
4 participants