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

VStream: Allow for automatic resume after Reshard across VStreams #15395

Merged
merged 11 commits into from
Mar 19, 2024

Conversation

mattlord
Copy link
Contributor

@mattlord mattlord commented Mar 2, 2024

Description

When we can see that a keyspace has been resharded — meaning that the keyspace has serving shards that differ from the ones provided in the current VStream RPC call, which are from the previous VStream client connection — then we include non-serving tablets in our tablet picker so that we can select the tablets from the old / now-non-serving shards in the keyspace in order to ensure that we stream all remaining GTIDs needed from those shards between what we had last streamed and when the Reshard cutover (SwitchTraffic or ReverseTraffic) took place, along with the Reshard journal event which allows us to then automatically and seamlessly start replicating from the beginning of time on the new shards.

The remaining limitation, which there is no way around, is that the old shards cannot be deleted in between the VStreams — as we need to connect to those to ensure we stream all of the GTIDs created there before transitioning to the new shards.

Click here for a manual test in this branch:
./101_initial_cluster.sh; mysql < ../common/insert_commerce_data.sql; ./201_customer_tablets.sh ; ./202_move_tables.sh; ./203_switch_reads.sh; ./204_switch_writes.sh; ./205_clean_commerce.sh

sleep 30 # VTGate's healthcheck cache has to be updated


# Update vstream_client example:
diff --git a/examples/local/vstream_client.go b/examples/local/vstream_client.go
index 98d2129f89..f5a7d40a45 100644
--- a/examples/local/vstream_client.go
+++ b/examples/local/vstream_client.go
@@ -38,7 +38,7 @@ import (
 */
 func main() {
        ctx := context.Background()
-       streamCustomer := true
+       streamCustomer := false
        var vgtid *binlogdatapb.VGtid
        if streamCustomer {
                vgtid = &binlogdatapb.VGtid{
@@ -56,7 +56,7 @@ func main() {
        } else {
                vgtid = &binlogdatapb.VGtid{
                        ShardGtids: []*binlogdatapb.ShardGtid{{
-                               Keyspace: "commerce",
+                               Keyspace: "customer",
                                Shard:    "0",
                                Gtid:     "",
                        }}}


go run vstream_client.go
# Save the GTID it shows (MySQL56/<uuid>:1-52)
# CTRL-C

# A GTID that we will need from the "old shard"
mysql -e "insert into customer (email) values ('[email protected]')"

./301_customer_sharded.sh; ./302_new_shards.sh; ./303_reshard.sh; ./304_switch_reads.sh; ./305_switch_writes.sh

sleep 30 # VTGate's healthcheck cache has to be updated


# Update the vstream_client example again, specifying the GTID we recorded from the previous client run
diff --git a/examples/local/vstream_client.go b/examples/local/vstream_client.go
index 98d2129f89..f5a7d40a45 100644
--- a/examples/local/vstream_client.go
+++ b/examples/local/vstream_client.go
@@ -38,7 +38,7 @@ import (
 */
 func main() {
        ctx := context.Background()
-       streamCustomer := true
+       streamCustomer := false
        var vgtid *binlogdatapb.VGtid
        if streamCustomer {
                vgtid = &binlogdatapb.VGtid{
@@ -56,7 +56,7 @@ func main() {
        } else {
                vgtid = &binlogdatapb.VGtid{
                        ShardGtids: []*binlogdatapb.ShardGtid{{
-                               Keyspace: "commerce",
+                               Keyspace: "customer",
                                Shard:    "0",
-                               Gtid:     "",
+                               Gtid:     "MySQL56/3578b494-d8c2-11ee-8c64-dfd798716dd1:1-52",
                        }}}


# A GTID that we will need from the "new shards"
mysql -e "insert into customer (email) values ('[email protected]')"

go run vstream_client.go

# In another shell; a new GTID on the new shards in our running stream
mysql -e "insert into customer (email) values ('[email protected]')"

Example final output:

❯ go run vstream_client.go

[type:BEGIN  timestamp:1709404214  current_time:1709404458792405000  keyspace:"customer"  shard:"0" type:FIELD  timestamp:1709404214  field_event:{table_name:"customer.customer"  fields:{name:"customer_id"  type:INT64  table:"customer"  org_table:"customer"  database:"vt_customer"  org_name:"customer_id"  column_length:20  charset:63  flags:53251  column_type:"bigint"}  fields:{name:"email"  type:VARBINARY  table:"customer"  org_table:"customer"  database:"vt_customer"  org_name:"email"  column_length:128  charset:63  flags:128  column_type:"varbinary(128)"}  keyspace:"customer"  shard:"0"}  current_time:1709404458794456000  keyspace:"customer"  shard:"0" type:ROW  timestamp:1709404214  row_event:{table_name:"customer.customer"  row_changes:{after:{lengths:1  lengths:21  values:"[email protected]"}}  keyspace:"customer"  shard:"0"  flags:1}  current_time:1709404458794467000  keyspace:"customer"  shard:"0" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"0"  gtid:"MySQL56/3578b494-d8c2-11ee-8c64-dfd798716dd1:1-53"}}  keyspace:"customer"  shard:"0" type:COMMIT  timestamp:1709404214  current_time:1709404458794474000  keyspace:"customer"  shard:"0"]
[type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"0"  gtid:"MySQL56/3578b494-d8c2-11ee-8c64-dfd798716dd1:1-54"}}  keyspace:"customer"  shard:"0" type:DDL  timestamp:1709404294  statement:"alter table customer change customer_id customer_id bigint not null"  current_time:1709404458800989000  keyspace:"customer"  shard:"0"]
[type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"0"  gtid:"MySQL56/3578b494-d8c2-11ee-8c64-dfd798716dd1:1-55"}}  keyspace:"customer"  shard:"0" type:OTHER  timestamp:1709404294  current_time:1709404458804184000  keyspace:"customer"  shard:"0"]
[type:BEGIN  timestamp:1709404294  current_time:1709404458804199000  keyspace:"customer"  shard:"0" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"0"  gtid:"MySQL56/3578b494-d8c2-11ee-8c64-dfd798716dd1:1-56"}}  keyspace:"customer"  shard:"0" type:COMMIT  timestamp:1709404294  current_time:1709404458804229000  keyspace:"customer"  shard:"0"]
[type:BEGIN  timestamp:1709404318  current_time:1709404458804246000  keyspace:"customer"  shard:"0" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"0"  gtid:"MySQL56/3578b494-d8c2-11ee-8c64-dfd798716dd1:1-57"}}  keyspace:"customer"  shard:"0" type:COMMIT  timestamp:1709404318  current_time:1709404458804262000  keyspace:"customer"  shard:"0"]
[type:BEGIN  timestamp:1709404318  current_time:1709404458804271000  keyspace:"customer"  shard:"0" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"0"  gtid:"MySQL56/3578b494-d8c2-11ee-8c64-dfd798716dd1:1-58"}}  keyspace:"customer"  shard:"0" type:COMMIT  timestamp:1709404318  current_time:1709404458804279000  keyspace:"customer"  shard:"0"]
[type:BEGIN  timestamp:1709404318  current_time:1709404458804288000  keyspace:"customer"  shard:"0" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"0"  gtid:"MySQL56/3578b494-d8c2-11ee-8c64-dfd798716dd1:1-59"}}  keyspace:"customer"  shard:"0" type:COMMIT  timestamp:1709404318  current_time:1709404458804295000  keyspace:"customer"  shard:"0"]
[type:BEGIN  timestamp:1709404318  current_time:1709404458804299000  keyspace:"customer"  shard:"0" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"0"  gtid:"MySQL56/3578b494-d8c2-11ee-8c64-dfd798716dd1:1-60"}}  keyspace:"customer"  shard:"0" type:COMMIT  timestamp:1709404318  current_time:1709404458804305000  keyspace:"customer"  shard:"0"]
[type:BEGIN  timestamp:1709404318  current_time:1709404458804311000  keyspace:"customer"  shard:"0" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"0"  gtid:"MySQL56/3578b494-d8c2-11ee-8c64-dfd798716dd1:1-61"}}  keyspace:"customer"  shard:"0" type:COMMIT  timestamp:1709404318  current_time:1709404458804318000  keyspace:"customer"  shard:"0"]
[type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"0"  gtid:"MySQL56/3578b494-d8c2-11ee-8c64-dfd798716dd1:1-62"}}  keyspace:"customer"  shard:"0" type:OTHER  timestamp:1709404318  current_time:1709404458804327000  keyspace:"customer"  shard:"0"]
[type:BEGIN  timestamp:1709404319  current_time:1709404458820681000  keyspace:"customer"  shard:"80-" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"-80"  gtid:"MySQL56/1953a1e2-d8c3-11ee-a728-c56fdc027239:1-48"}  shard_gtids:{keyspace:"customer"  shard:"80-"  gtid:"MySQL56/20f57e20-d8c3-11ee-8aa0-0a7f6065da16:1-49"}}  keyspace:"customer"  shard:"80-" type:COMMIT  timestamp:1709404319  current_time:1709404458820698000  keyspace:"customer"  shard:"80-"]
[type:BEGIN  timestamp:1709404319  current_time:1709404458820719000  keyspace:"customer"  shard:"80-" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"-80"  gtid:"MySQL56/1953a1e2-d8c3-11ee-a728-c56fdc027239:1-48"}  shard_gtids:{keyspace:"customer"  shard:"80-"  gtid:"MySQL56/20f57e20-d8c3-11ee-8aa0-0a7f6065da16:1-50"}}  keyspace:"customer"  shard:"80-" type:COMMIT  timestamp:1709404319  current_time:1709404458820726000  keyspace:"customer"  shard:"80-"]
[type:BEGIN  timestamp:1709404319  current_time:1709404458820731000  keyspace:"customer"  shard:"80-" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"-80"  gtid:"MySQL56/1953a1e2-d8c3-11ee-a728-c56fdc027239:1-48"}  shard_gtids:{keyspace:"customer"  shard:"80-"  gtid:"MySQL56/20f57e20-d8c3-11ee-8aa0-0a7f6065da16:1-51"}}  keyspace:"customer"  shard:"80-" type:COMMIT  timestamp:1709404319  current_time:1709404458820738000  keyspace:"customer"  shard:"80-"]
[type:BEGIN  timestamp:1709404319  current_time:1709404458820597000  keyspace:"customer"  shard:"-80" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"-80"  gtid:"MySQL56/1953a1e2-d8c3-11ee-a728-c56fdc027239:1-49"}  shard_gtids:{keyspace:"customer"  shard:"80-"  gtid:"MySQL56/20f57e20-d8c3-11ee-8aa0-0a7f6065da16:1-51"}}  keyspace:"customer"  shard:"-80" type:COMMIT  timestamp:1709404319  current_time:1709404458820611000  keyspace:"customer"  shard:"-80"]
[type:BEGIN  timestamp:1709404319  current_time:1709404458820625000  keyspace:"customer"  shard:"-80" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"-80"  gtid:"MySQL56/1953a1e2-d8c3-11ee-a728-c56fdc027239:1-50"}  shard_gtids:{keyspace:"customer"  shard:"80-"  gtid:"MySQL56/20f57e20-d8c3-11ee-8aa0-0a7f6065da16:1-51"}}  keyspace:"customer"  shard:"-80" type:COMMIT  timestamp:1709404319  current_time:1709404458820649000  keyspace:"customer"  shard:"-80"]
[type:BEGIN  timestamp:1709404319  current_time:1709404458820671000  keyspace:"customer"  shard:"-80" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"-80"  gtid:"MySQL56/1953a1e2-d8c3-11ee-a728-c56fdc027239:1-51"}  shard_gtids:{keyspace:"customer"  shard:"80-"  gtid:"MySQL56/20f57e20-d8c3-11ee-8aa0-0a7f6065da16:1-51"}}  keyspace:"customer"  shard:"-80" type:COMMIT  timestamp:1709404319  current_time:1709404458820677000  keyspace:"customer"  shard:"-80"]
[type:BEGIN  timestamp:1709404447  current_time:1709404458820683000  keyspace:"customer"  shard:"-80" type:FIELD  timestamp:1709404447  field_event:{table_name:"customer.customer"  fields:{name:"customer_id"  type:INT64  table:"customer"  org_table:"customer"  database:"vt_customer"  org_name:"customer_id"  column_length:20  charset:63  flags:53251  column_type:"bigint"}  fields:{name:"email"  type:VARBINARY  table:"customer"  org_table:"customer"  database:"vt_customer"  org_name:"email"  column_length:128  charset:63  flags:128  column_type:"varbinary(128)"}  keyspace:"customer"  shard:"-80"}  current_time:1709404458821934000  keyspace:"customer"  shard:"-80" type:ROW  timestamp:1709404447  row_event:{table_name:"customer.customer"  row_changes:{after:{lengths:4  lengths:22  values:"[email protected]"}}  keyspace:"customer"  shard:"-80"  flags:1}  current_time:1709404458821946000  keyspace:"customer"  shard:"-80" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"-80"  gtid:"MySQL56/1953a1e2-d8c3-11ee-a728-c56fdc027239:1-52"}  shard_gtids:{keyspace:"customer"  shard:"80-"  gtid:"MySQL56/20f57e20-d8c3-11ee-8aa0-0a7f6065da16:1-51"}}  keyspace:"customer"  shard:"-80" type:COMMIT  timestamp:1709404447  current_time:1709404458821956000  keyspace:"customer"  shard:"-80"]



[type:BEGIN  timestamp:1709404466  current_time:1709404466674498000  keyspace:"customer"  shard:"80-" type:FIELD  timestamp:1709404466  field_event:{table_name:"customer.customer"  fields:{name:"customer_id"  type:INT64  table:"customer"  org_table:"customer"  database:"vt_customer"  org_name:"customer_id"  column_length:20  charset:63  flags:53251  column_type:"bigint"}  fields:{name:"email"  type:VARBINARY  table:"customer"  org_table:"customer"  database:"vt_customer"  org_name:"email"  column_length:128  charset:63  flags:128  column_type:"varbinary(128)"}  keyspace:"customer"  shard:"80-"}  current_time:1709404466675930000  keyspace:"customer"  shard:"80-" type:ROW  timestamp:1709404466  row_event:{table_name:"customer.customer"  row_changes:{after:{lengths:4  lengths:22  values:"[email protected]"}}  keyspace:"customer"  shard:"80-"  flags:1}  current_time:1709404466675945000  keyspace:"customer"  shard:"80-" type:VGTID  vgtid:{shard_gtids:{keyspace:"customer"  shard:"-80"  gtid:"MySQL56/1953a1e2-d8c3-11ee-a728-c56fdc027239:1-52"}  shard_gtids:{keyspace:"customer"  shard:"80-"  gtid:"MySQL56/20f57e20-d8c3-11ee-8aa0-0a7f6065da16:1-52"}}  keyspace:"customer"  shard:"80-" type:COMMIT  timestamp:1709404466  current_time:1709404466675950000  keyspace:"customer"  shard:"80-"]

Related Issue(s)

Checklist

  • "Backport to:" labels have been added if this change should be back-ported to release branches
  • If this change is to be back-ported to previous releases, a justification is included in the PR description
  • Tests were added or are not required
  • Did the new or modified tests pass consistently locally and on CI?
  • Documentation: VStream: Add notes about reshard handling website#1700

Copy link
Contributor

vitess-bot bot commented Mar 2, 2024

Review Checklist

Hello reviewers! 👋 Please follow this checklist when reviewing this Pull Request.

General

  • Ensure that the Pull Request has a descriptive title.
  • Ensure there is a link to an issue (except for internal cleanup and flaky test fixes), new features should have an RFC that documents use cases and test cases.

Tests

  • Bug fixes should have at least one unit or end-to-end test, enhancement and new features should have a sufficient number of tests.

Documentation

  • Apply the release notes (needs details) label if users need to know about this change.
  • New features should be documented.
  • There should be some code comments as to why things are implemented the way they are.
  • There should be a comment at the top of each new or modified test to explain what the test does.

New flags

  • Is this flag really necessary?
  • Flag names must be clear and intuitive, use dashes (-), and have a clear help text.

If a workflow is added or modified:

  • Each item in Jobs should be named in order to mark it as required.
  • If the workflow needs to be marked as required, the maintainer team must be notified.

Backward compatibility

  • Protobuf changes should be wire-compatible.
  • Changes to _vt tables and RPCs need to be backward compatible.
  • RPC changes should be compatible with vitess-operator
  • If a flag is removed, then it should also be removed from vitess-operator and arewefastyet, if used there.
  • vtctl command output order should be stable and awk-able.

@vitess-bot vitess-bot bot added NeedsBackportReason If backport labels have been applied to a PR, a justification is required NeedsDescriptionUpdate The description is not clear or comprehensive enough, and needs work NeedsIssue A linked issue is missing for this Pull Request NeedsWebsiteDocsUpdate What it says labels Mar 2, 2024
@github-actions github-actions bot added this to the v20.0.0 milestone Mar 2, 2024
@mattlord mattlord added Type: Enhancement Logical improvement (somewhere between a bug and feature) and removed NeedsWebsiteDocsUpdate What it says NeedsBackportReason If backport labels have been applied to a PR, a justification is required labels Mar 2, 2024
@mattlord mattlord force-pushed the vtgate_vstream_reshard_resume branch 3 times, most recently from 1d284dc to e5d3048 Compare March 2, 2024 18:44
Copy link

codecov bot commented Mar 2, 2024

Codecov Report

Attention: Patch coverage is 76.19048% with 10 lines in your changes are missing coverage. Please review.

Project coverage is 65.69%. Comparing base (2ee5946) to head (2ca07bb).
Report is 5 commits behind head on main.

Files Patch % Lines
go/vt/vtgate/vstream_manager.go 76.19% 10 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #15395      +/-   ##
==========================================
+ Coverage   65.65%   65.69%   +0.03%     
==========================================
  Files        1563     1564       +1     
  Lines      194423   194623     +200     
==========================================
+ Hits       127658   127863     +205     
+ Misses      66765    66760       -5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@mattlord mattlord removed the NeedsDescriptionUpdate The description is not clear or comprehensive enough, and needs work label Mar 2, 2024
@mattlord mattlord changed the title VStream: Allow for automatic resume after reshard VStream: Allow for automatic resume after Reshard Mar 2, 2024
@mattlord mattlord force-pushed the vtgate_vstream_reshard_resume branch 7 times, most recently from b5b7974 to dc80682 Compare March 3, 2024 16:36
@mattlord mattlord force-pushed the vtgate_vstream_reshard_resume branch from dc80682 to d967187 Compare March 3, 2024 16:41
Signed-off-by: Matt Lord <[email protected]>
@mattlord mattlord force-pushed the vtgate_vstream_reshard_resume branch 2 times, most recently from a501e62 to 623cfdb Compare March 4, 2024 17:13
Signed-off-by: Matt Lord <[email protected]>
@mattlord mattlord force-pushed the vtgate_vstream_reshard_resume branch from 623cfdb to 77894d7 Compare March 4, 2024 17:15
mattlord added 3 commits March 4, 2024 12:33
Signed-off-by: Matt Lord <[email protected]>
Signed-off-by: Matt Lord <[email protected]>
@mattlord mattlord changed the title VStream: Allow for automatic resume after Reshard VStream: Allow for automatic resume after Reshard across VStreams Mar 4, 2024
@mattlord mattlord removed the NeedsIssue A linked issue is missing for this Pull Request label Mar 4, 2024
@mattlord mattlord marked this pull request as ready for review March 4, 2024 18:34
Signed-off-by: Matt Lord <[email protected]>
@mattlord mattlord force-pushed the vtgate_vstream_reshard_resume branch from 775ee87 to 3ed17b0 Compare March 5, 2024 04:36
Signed-off-by: Matt Lord <[email protected]>
Copy link
Contributor

@rohit-nayak-ps rohit-nayak-ps left a comment

Choose a reason for hiding this comment

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

Looks good.

go/test/endtoend/vreplication/vstream_test.go Show resolved Hide resolved
Comment on lines 974 to 988
// Now that we know there MAY have been an applicable reshard, let's make a
// definitive determination by looking at the shard keyranges.
for _, i := range shards {
for _, j := range shards {
if i.ShardName() == j.ShardName() && key.KeyRangeEqual(i.GetKeyRange(), j.GetKeyRange()) {
// It's the same shard so skip it.
continue
}
if key.KeyRangeIntersect(i.GetKeyRange(), j.GetKeyRange()) {
// We have different shards with overlapping keyranges so we know
// that a reshard has happened.
return true, nil
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Overall, LGTM. If it ever becomes a concern, then we can improve the performance of this code by sorting the two lists of shards and then reading from both simultaneously once.

Copy link
Contributor Author

@mattlord mattlord Mar 18, 2024

Choose a reason for hiding this comment

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

It's a single map of shards. It's all of the shards in the keyspace, so e.g. if a keyspace is being sharded for the first time the list could be:

-
-80
80-

In that case we would take the first one, then compare it with -80 and see that they have overlapping key ranges.

@mattlord mattlord merged commit d20f3c5 into vitessio:main Mar 19, 2024
102 checks passed
@mattlord mattlord deleted the vtgate_vstream_reshard_resume branch March 19, 2024 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: VReplication Type: Enhancement Logical improvement (somewhere between a bug and feature)
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Feature Request: support automatic reshard handling across VStreams
3 participants