-
Notifications
You must be signed in to change notification settings - Fork 4.5k
[Spanner Change Streams] Fix potential data loss issue by ensuring to only claim timestamps that have been fully processed from the restriction tracker. #37326
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -303,14 +303,24 @@ public ProcessContinuation run( | |
| throw e; | ||
| } | ||
|
|
||
| LOG.debug("[{}] change stream completed successfully", token); | ||
| if (tracker.tryClaim(endTimestamp)) { | ||
| LOG.debug( | ||
| "[{}] change stream completed successfully up to {}", token, changeStreamQueryEndTimestamp); | ||
| if (!tracker.tryClaim(changeStreamQueryEndTimestamp)) { | ||
| return ProcessContinuation.stop(); | ||
| } | ||
|
|
||
| if (changeStreamQueryEndTimestamp.equals(endTimestamp)) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should here be >= or just = or no difference?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems not correct if we have partition terminate case. changeStreamQueryEndTimestamp will not be equal to endTimestamp for terminated partition, so the partition will not be marked finished. |
||
| LOG.debug("[{}] Finishing partition", token); | ||
| // TODO: This should be performed after the commit succeeds. Since bundle finalizers are not | ||
| // guaranteed to be called, this needs to be performed in a subsequent fused stage. | ||
| partitionMetadataDao.updateToFinished(token); | ||
| metrics.decActivePartitionReadCounter(); | ||
| LOG.info("[{}] After attempting to finish the partition", token); | ||
| return ProcessContinuation.stop(); | ||
| } | ||
| return ProcessContinuation.stop(); | ||
|
|
||
| LOG.info("[{}] Rescheduling partition where query completed due to not being finished", token); | ||
| return ProcessContinuation.resume(); | ||
| } | ||
|
|
||
| private BundleFinalizer.Callback updateWatermarkCallback( | ||
|
|
@@ -339,8 +349,8 @@ private boolean isTimestampOutOfRange(SpannerException e) { | |
| } | ||
|
|
||
| // Return (now + 2 mins) as the end timestamp for reading change streams. This is only used if | ||
| // users want to run the connector forever. This approach works because Google Dataflow | ||
| // checkpoints every 5s or 5MB output provided and the change stream query has deadline for 1 min. | ||
| // users want to run the connector forever. If the end timestamp is reached, we will resume | ||
| // processing from that timestamp on a subsequent DoFn execution. | ||
| private Timestamp getNextReadChangeStreamEndTimestamp() { | ||
| final Timestamp current = Timestamp.now(); | ||
| return Timestamp.ofTimeSecondsAndNanos(current.getSeconds() + 2 * 60, current.getNanos()); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sam, "An unbounded end timestamp is no longer allowed for the change stream query rpc. However if we reach the end timestamp we should be careful to only advance the tracker to this timestamp and not the possibly unbounded end timestamp of the range." Just a caution to confirm with you: