Repository: vitessio/vitess
Pull request #9554 (2022-01-24 11:51:18)

non-unique vindex routing in update and delete query
<!--
  Thank you for your contribution to the Vitess project.
  How to contribute: https://vitess.io/docs/contributing/
  Please first make sure there is an open Issue to discuss the feature/fix suggested in this PR.
  If this is a new feature, please mark the Issue as "RFC".
 -->

<!-- if this PR is Work in Progress please create it as a Draft Pull Request -->

## Description
<!-- A few sentences describing the overall goals of the pull request's commits. -->
<!-- If this is a bug fix and you think the fix should be backported, please write so. -->

This PR adds supported for extracting routing information from update/delete query and using non-unique lookup vindex if available and having lowest cost among other options.

## Related Issue(s)
<!-- List related issues and pull requests. If this PR fixes an issue, please add it using Fixes #????  -->

## Checklist
- [X] Tests were added or are not required
- [X] Documentation was added or is not required

## Deployment Notes
<!-- Notes regarding deployment of the contained body of work. These should note any db migrations, etc. -->


Patch:
diff --git a/doc/releasenotes/13_0_0_summary.md b/doc/releasenotes/13_0_0_summary.md
index 58f4ada45c..402fa4bb6b 100644
--- a/doc/releasenotes/13_0_0_summary.md
+++ b/doc/releasenotes/13_0_0_summary.md
@@ -80,10 +80,6 @@ vtctlclient OnlineDDL ApplySchema -sql "drop table t1, drop table t2" -uuid_list
 Vitess will assign each migration with given UUID in order of appearance.
 It is the user's responsibility to ensure given UUIDs are globally unique. If the user submits a migration with an already existing UUID, that migration never gets scheduled nor executed.
 
-### vtctl/vtctlclient ApplySchema -migration_context
-
-`-migration_context` flag is synonymous to `-request_context`. Either will work. We will encourage use of `-migration_context` as it is more consistent with output of `SHOW VITESS_MIGRATIONS ...` which includes the `migration_context` column.
-
 ### vtctl/vtctlclient OnlineDDL ... complete
 
 Complementing the `alter vitess_migration ... complete` query, a migration can also be completed via `vtctl` or `vtctlclient`:
@@ -98,10 +94,6 @@ For example:
 vtctlclient OnlineDDL commerce complete d08ffe6b_51c9_11ec_9cf2_0a43f95f28a3
 ```
 
-### vtctl/vtctlclient OnlineDDL -json
-
-The command now accepts an optional `-json` flag. With this flag, the output is a valid JSON listing all columns and rows.
-
 ## Incompatible Changes
 
 ## Deprecations
diff --git a/examples/local/backups/create_commerce_schema.sql b/examples/local/backups/create_commerce_schema.sql
deleted file mode 100644
index 68c52fefeb..0000000000
--- a/examples/local/backups/create_commerce_schema.sql
+++ /dev/null
@@ -1,11 +0,0 @@
-create table product(
-    sku varbinary(128),
-    description varbinary(128),
-    price bigint,
-    primary key(sku)
-) ENGINE=InnoDB;
-
-create table customer_seq(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence';
-insert into customer_seq(id, next_id, cache) values(0, 1000, 100);
-create table order_seq(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence';
-insert into order_seq(id, next_id, cache) values(0, 1000, 100);
diff --git a/examples/local/backups/create_customer_schema.sql b/examples/local/backups/create_customer_schema.sql
deleted file mode 100644
index 07a614ffd4..0000000000
--- a/examples/local/backups/create_customer_schema.sql
+++ /dev/null
@@ -1,13 +0,0 @@
-create table customer(
-    customer_id bigint not null,
-    email varbinary(128),
-    primary key(customer_id)
-) ENGINE=InnoDB;
-
-create table corder(
-    order_id bigint not null,
-    customer_id bigint,
-    sku varbinary(128),
-    price bigint,
-    primary key(order_id)
-) ENGINE=InnoDB;
\ No newline at end of file
diff --git a/examples/local/backups/restart_tablets.sh b/examples/local/backups/restart_tablets.sh
deleted file mode 100755
index 2c6aa19aa4..0000000000
--- a/examples/local/backups/restart_tablets.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-
-# Copyright 2022 The Vitess Authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# this script brings up new tablets for the two new shards that we will
-# be creating in the customer keyspace and copies the schema
-
-source ./env.sh
-
-for i in 100 101 102; do
-  CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh
-  CELL=zone1 KEYSPACE=commerce TABLET_UID=$i ./scripts/vttablet-up.sh
-done
-sleep 5
-vtctldclient InitShardPrimary --force commerce/0 zone1-100
-
-for i in 200 201 202; do
-  CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh
-  SHARD=-80 CELL=zone1 KEYSPACE=customer TABLET_UID=$i ./scripts/vttablet-up.sh
-done
-sleep 5
-vtctldclient InitShardPrimary --force customer/-80 zone1-200
-
-for i in 300 301 302; do
-  CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh
-  SHARD=80- CELL=zone1 KEYSPACE=customer TABLET_UID=$i ./scripts/vttablet-up.sh
-done
-sleep 5
-vtctldclient InitShardPrimary --force customer/80- zone1-300
\ No newline at end of file
diff --git a/examples/local/backups/start_cluster.sh b/examples/local/backups/start_cluster.sh
deleted file mode 100755
index d1c8261c69..0000000000
--- a/examples/local/backups/start_cluster.sh
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/bash
-
-# Copyright 2022 The Vitess Authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# this script brings up new tablets for the two new shards that we will
-# be creating in the customer keyspace and copies the schema
-
-source ./env.sh
-
-# start topo server
-if [ "${TOPO}" = "zk2" ]; then
-	CELL=zone1 ./scripts/zk-up.sh
-elif [ "${TOPO}" = "k8s" ]; then
-	CELL=zone1 ./scripts/k3s-up.sh
-else
-	CELL=zone1 ./scripts/etcd-up.sh
-fi
-
-# start vtctld
-CELL=zone1 ./scripts/vtctld-up.sh
-
-
-# start vttablets for keyspace commerce
-for i in 100 101 102; do
-	CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh
-	CELL=zone1 KEYSPACE=commerce TABLET_UID=$i ./scripts/vttablet-up.sh
-done
-
-# set one of the replicas to primary
-vtctldclient InitShardPrimary --force commerce/0 zone1-100
-
-# create the schema for commerce
-vtctlclient ApplySchema -sql-file backups/create_commerce_schema.sql commerce
-vtctlclient ApplyVSchema -vschema_file ./vschema_commerce_seq.json commerce
-
-
-# start vttablets for keyspace customer
-for i in 200 201 202; do
-	CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh
-	SHARD=-80 CELL=zone1 KEYSPACE=customer TABLET_UID=$i ./scripts/vttablet-up.sh
-done
-for i in 300 301 302; do
-	CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh
-	SHARD=80- CELL=zone1 KEYSPACE=customer TABLET_UID=$i ./scripts/vttablet-up.sh
-done
-
-# set one of the replicas to primary
-vtctldclient InitShardPrimary --force customer/-80 zone1-200
-vtctldclient InitShardPrimary --force customer/80- zone1-300
-
-# create the schema for customer
-vtctlclient ApplySchema -sql-file backups/create_customer_schema.sql customer
-vtctlclient ApplyVSchema -vschema_file ./vschema_customer_sharded.json customer
-
-
-# start vtgate
-CELL=zone1 ./scripts/vtgate-up.sh
-
-sleep 5
-
-mysql < ../common/insert_commerce_data.sql
diff --git a/examples/local/backups/stop_tablets.sh b/examples/local/backups/stop_tablets.sh
deleted file mode 100755
index f3359bff55..0000000000
--- a/examples/local/backups/stop_tablets.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-
-# Copyright 2022 The Vitess Authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# this script brings up new tablets for the two new shards that we will
-# be creating in the customer keyspace and copies the schema
-
-source ./env.sh
-
-for tablet in 100 200 300; do
-  if vtctlclient -action_timeout 1s -server localhost:15999 GetTablet zone1-$tablet >/dev/null 2>&1; then
-    # The zero tablet is up. Try to shutdown 0-2 tablet + mysqlctl
-    for i in 0 1 2; do
-      uid=$(($tablet + $i))
-      echo "Shutting down tablet zone1-$uid"
-      CELL=zone1 TABLET_UID=$uid ./scripts/vttablet-down.sh
-      echo "Shutting down mysql zone1-$uid"
-      CELL=zone1 TABLET_UID=$uid ./scripts/mysqlctl-down.sh
-      echo "Removing tablet directory zone1-$uid"
-      vtctlclient DeleteTablet -allow_primary=true zone1-$uid
-      rm -Rf $VTDATAROOT/vt_0000000$uid
-    done
-  fi
-done
\ No newline at end of file
diff --git a/examples/local/backups/take_backups.sh b/examples/local/backups/take_backups.sh
deleted file mode 100755
index f8544a95b6..0000000000
--- a/examples/local/backups/take_backups.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-
-# Copyright 2022 The Vitess Authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# this script brings up new tablets for the two new shards that we will
-# be creating in the customer keyspace and copies the schema
-
-source ./env.sh
-
-vtctlclient BackupShard customer/-80
-vtctlclient BackupShard customer/80-
-vtctlclient BackupShard commerce/0
diff --git a/examples/local/scripts/vttablet-up.sh b/examples/local/scripts/vttablet-up.sh
index 1bac56e8de..c3f66fa806 100755
--- a/examples/local/scripts/vttablet-up.sh
+++ b/examples/local/scripts/vttablet-up.sh
@@ -34,7 +34,6 @@ if [[ "${uid: -1}" -gt 1 ]]; then
 fi
 
 echo "Starting vttablet for $alias..."
-
 # shellcheck disable=SC2086
 vttablet \
  $TOPOLOGY_FLAGS \
diff --git a/examples/operator/README.md b/examples/operator/README.md
index 96fb150689..cb3164e578 100644
--- a/examples/operator/README.md
+++ b/examples/operator/README.md
@@ -8,15 +8,8 @@ minikube start --cpus=8 --memory=11000 --disk-size=50g --kubernetes-version=v1.1
 kubectl apply -f operator.yaml
 
 # Bring up initial cluster and commerce keyspace
-# NOTE: If you are using MySQL 8, update the images section to use mysql80 images
-# Example:
-#  images:
-#    vtctld: vitess/lite:v12.0.0-mysql80
-#    vtgate: vitess/lite:v12.0.0-mysql80
-#    vttablet: vitess/lite:v12.0.0-mysql80
-#    vtbackup: vitess/lite:v12.0.0-mysql80
-#    mysqld:
-#      mysql80Compatible: vitess/lite:v12.0.0-mysql80
+# NOTE: If you are using MySQL 8, update images section with `-mysql80` tag.
+# Example: `vtctld: vitess/lite:v12.0.0-mysql80` 
 
 kubectl apply -f 101_initial_cluster.yaml
 
diff --git a/go/mysql/conn.go b/go/mysql/conn.go
index ab4b50ab1b..15db83e070 100644
--- a/go/mysql/conn.go
+++ b/go/mysql/conn.go
@@ -195,8 +195,8 @@ type Conn struct {
 	sequence uint8
 }
 
-// splitStatementFunciton is the function that is used to split the statement in case of a multi-statement query.
-var splitStatementFunction = sqlparser.SplitStatementToPieces
+// splitStatementFunciton is the function that is used to split the statement in cas ef a multi-statement query.
+var splitStatementFunction func(blob string) (pieces []string, err error) = sqlparser.SplitStatementToPieces
 
 // PrepareData is a buffer used for store prepare statement meta data
 type PrepareData struct {
diff --git a/go/vt/schema/online_ddl.go b/go/vt/schema/online_ddl.go
index 7c731dbd1a..c6a25b5e73 100644
--- a/go/vt/schema/online_ddl.go
+++ b/go/vt/schema/online_ddl.go
@@ -111,18 +111,18 @@ const (
 
 // OnlineDDL encapsulates the relevant information in an online schema change request
 type OnlineDDL struct {
-	Keyspace         string          `json:"keyspace,omitempty"`
-	Table            string          `json:"table,omitempty"`
-	Schema           string          `json:"schema,omitempty"`
-	SQL              string          `json:"sql,omitempty"`
-	UUID             string          `json:"uuid,omitempty"`
-	Strategy         DDLStrategy     `json:"strategy,omitempty"`
-	Options          string          `json:"options,omitempty"`
-	RequestTime      int64           `json:"time_created,omitempty"`
-	MigrationContext string          `json:"context,omitempty"`
-	Status           OnlineDDLStatus `json:"status,omitempty"`
-	TabletAlias      string          `json:"tablet,omitempty"`
-	Retries          int64           `json:"retries,omitempty"`
+	Keyspace       string          `json:"keyspace,omitempty"`
+	Table          string          `json:"table,omitempty"`
+	Schema         string          `json:"schema,omitempty"`
+	SQL            string          `json:"sql,omitempty"`
+	UUID           string          `json:"uuid,omitempty"`
+	Strategy       DDLStrategy     `json:"strategy,omitempty"`
+	Options        string          `json:"options,omitempty"`
+	RequestTime    int64           `json:"time_created,omitempty"`
+	RequestContext string          `json:"context,omitempty"`
+	Status         OnlineDDLStatus `json:"status,omitempty"`
+	TabletAlias    string          `json:"tablet,omitempty"`
+	Retries        int64           `json:"retries,omitempty"`
 }
 
 // FromJSON creates an OnlineDDL from json
@@ -181,12 +181,12 @@ func onlineDDLStatementSanity(sql string, ddlStmt sqlparser.DDLStatement) error
 }
 
 // NewOnlineDDLs takes a single DDL statement, normalizes it (potentially break down into multiple statements), and generates one or more OnlineDDL instances, one for each normalized statement
-func NewOnlineDDLs(keyspace string, sql string, ddlStmt sqlparser.DDLStatement, ddlStrategySetting *DDLStrategySetting, migrationContext string, providedUUID string) (onlineDDLs [](*OnlineDDL), err error) {
+func NewOnlineDDLs(keyspace string, sql string, ddlStmt sqlparser.DDLStatement, ddlStrategySetting *DDLStrategySetting, requestContext string, providedUUID string) (onlineDDLs [](*OnlineDDL), err error) {
 	appendOnlineDDL := func(tableName string, ddlStmt sqlparser.DDLStatement) error {
 		if err := onlineDDLStatementSanity(sql, ddlStmt); err != nil {
 			return err
 		}
-		onlineDDL, err := NewOnlineDDL(keyspace, tableName, sqlparser.String(ddlStmt), ddlStrategySetting, migrationContext, providedUUID)
+		onlineDDL, err := NewOnlineDDL(keyspace, tableName, sqlparser.String(ddlStmt), ddlStrategySetting, requestContext, providedUUID)
 		if err != nil {
 			return err
 		}
@@ -217,7 +217,7 @@ func NewOnlineDDLs(keyspace string, sql string, ddlStmt sqlparser.DDLStatement,
 }
 
 // NewOnlineDDL creates a schema change request with self generated UUID and RequestTime
-func NewOnlineDDL(keyspace string, table string, sql string, ddlStrategySetting *DDLStrategySetting, migrationContext string, providedUUID string) (onlineDDL *OnlineDDL, err error) {
+func NewOnlineDDL(keyspace string, table string, sql string, ddlStrategySetting *DDLStrategySetting, requestContext string, providedUUID string) (onlineDDL *OnlineDDL, err error) {
 	if ddlStrategySetting == nil {
 		return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "NewOnlineDDL: found nil DDLStrategySetting")
 	}
@@ -244,7 +244,7 @@ func NewOnlineDDL(keyspace string, table string, sql string, ddlStrategySetting
 			comments = sqlparser.Comments{
 				fmt.Sprintf(`/*vt+ uuid=%s context=%s table=%s strategy=%s options=%s */`,
 					encodeDirective(onlineDDLUUID),
-					encodeDirective(migrationContext),
+					encodeDirective(requestContext),
 					encodeDirective(table),
 					encodeDirective(string(ddlStrategySetting.Strategy)),
 					encodeDirective(ddlStrategySetting.Options),
@@ -282,15 +282,15 @@ func NewOnlineDDL(keyspace string, table string, sql string, ddlStrategySetting
 	}
 
 	return &OnlineDDL{
-		Keyspace:         keyspace,
-		Table:            table,
-		SQL:              sql,
-		UUID:             onlineDDLUUID,
-		Strategy:         ddlStrategySetting.Strategy,
-		Options:          ddlStrategySetting.Options,
-		RequestTime:      time.Now().UnixNano(),
-		MigrationContext: migrationContext,
-		Status:           OnlineDDLStatusRequested,
+		Keyspace:       keyspace,
+		Table:          table,
+		SQL:            sql,
+		UUID:           onlineDDLUUID,
+		Strategy:       ddlStrategySetting.Strategy,
+		Options:        ddlStrategySetting.Options,
+		RequestTime:    time.Now().UnixNano(),
+		RequestContext: requestContext,
+		Status:         OnlineDDLStatusRequested,
 	}, nil
 }
 
@@ -358,7 +358,7 @@ func OnlineDDLFromCommentedStatement(stmt sqlparser.Statement) (onlineDDL *Onlin
 	} else {
 		return nil, err
 	}
-	if onlineDDL.MigrationContext, err = decodeDirective("context"); err != nil {
+	if onlineDDL.RequestContext, err = decodeDirective("context"); err != nil {
 		return nil, err
 	}
 	return onlineDDL, nil
diff --git a/go/vt/schemamanager/tablet_executor.go b/go/vt/schemamanager/tablet_executor.go
index 3d7c58f1a7..f22f6abe50 100644
--- a/go/vt/schemamanager/tablet_executor.go
+++ b/go/vt/schemamanager/tablet_executor.go
@@ -36,7 +36,7 @@ import (
 
 // TabletExecutor applies schema changes to all tablets.
 type TabletExecutor struct {
-	migrationContext     string
+	requestContext       string
 	wr                   *wrangler.Wrangler
 	tablets              []*topodatapb.Tablet
 	isClosed             bool
@@ -49,13 +49,13 @@ type TabletExecutor struct {
 }
 
 // NewTabletExecutor creates a new TabletExecutor instance
-func NewTabletExecutor(migrationContext string, wr *wrangler.Wrangler, waitReplicasTimeout time.Duration) *TabletExecutor {
+func NewTabletExecutor(requestContext string, wr *wrangler.Wrangler, waitReplicasTimeout time.Duration) *TabletExecutor {
 	return &TabletExecutor{
 		wr:                   wr,
 		isClosed:             true,
 		allowBigSchemaChange: false,
 		waitReplicasTimeout:  waitReplicasTimeout,
-		migrationContext:     migrationContext,
+		requestContext:       requestContext,
 	}
 }
 
@@ -270,7 +270,7 @@ func (exec *TabletExecutor) executeSQL(ctx context.Context, sql string, provided
 	switch stmt := stmt.(type) {
 	case sqlparser.DDLStatement:
 		if exec.isOnlineSchemaDDL(stmt) {
-			onlineDDLs, err := schema.NewOnlineDDLs(exec.keyspace, sql, stmt, exec.ddlStrategySetting, exec.migrationContext, providedUUID)
+			onlineDDLs, err := schema.NewOnlineDDLs(exec.keyspace, sql, stmt, exec.ddlStrategySetting, exec.requestContext, providedUUID)
 			if err != nil {
 				execResult.ExecutorErr = err.Error()
 				return err
@@ -285,7 +285,7 @@ func (exec *TabletExecutor) executeSQL(ctx context.Context, sql string, provided
 		}
 	case *sqlparser.RevertMigration:
 		strategySetting := schema.NewDDLStrategySetting(schema.DDLStrategyOnline, exec.ddlStrategySetting.Options)
-		onlineDDL, err := schema.NewOnlineDDL(exec.keyspace, "", sqlparser.String(stmt), strategySetting, exec.migrationContext, providedUUID)
+		onlineDDL, err := schema.NewOnlineDDL(exec.keyspace, "", sqlparser.String(stmt), strategySetting, exec.requestContext, providedUUID)
 		if err != nil {
 			execResult.ExecutorErr = err.Error()
 			return err
diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go
index 7280a329dc..34c789cce0 100644
--- a/go/vt/vtctl/vtctl.go
+++ b/go/vt/vtctl/vtctl.go
@@ -641,8 +641,8 @@ var commands = []commandGroup{
 			{
 				name:   "ApplySchema",
 				method: commandApplySchema,
-				params: "[-allow_long_unavailability] [-wait_replicas_timeout=10s] [-ddl_strategy=<ddl_strategy>] [-uuid_list=<comma_separated_uuids>] [-migration_context=<unique-request-context>] [-skip_preflight] {-sql=<sql> || -sql-file=<filename>} <keyspace>",
-				help:   "Applies the schema change to the specified keyspace on every primary, running in parallel on all shards. The changes are then propagated to replicas via replication. If -allow_long_unavailability is set, schema changes affecting a large number of rows (and possibly incurring a longer period of unavailability) will not be rejected. -ddl_strategy is used to instruct migrations via vreplication, gh-ost or pt-osc with optional parameters. -migration_context allows the user to specify a custom request context for online DDL migrations. If -skip_preflight, SQL goes directly to shards without going through sanity checks.",
+				params: "[-allow_long_unavailability] [-wait_replicas_timeout=10s] [-ddl_strategy=<ddl_strategy>] [-uuid_list=<comma_separated_uuids>] [-request_context=<unique-request-context>] [-skip_preflight] {-sql=<sql> || -sql-file=<filename>} <keyspace>",
+				help:   "Applies the schema change to the specified keyspace on every primary, running in parallel on all shards. The changes are then propagated to replicas via replication. If -allow_long_unavailability is set, schema changes affecting a large number of rows (and possibly incurring a longer period of unavailability) will not be rejected. -ddl_strategy is used to instruct migrations via vreplication, gh-ost or pt-osc with optional parameters. -request_context allows the user to specify a custom request context for online DDL migrations. If -skip_preflight, SQL goes directly to shards without going through sanity checks.",
 			},
 			{
 				name:   "CopySchemaShard",
@@ -653,7 +653,7 @@ var commands = []commandGroup{
 			{
 				name:   "OnlineDDL",
 				method: commandOnlineDDL,
-				params: "[-json] <keyspace> <command> [<migration_uuid>]",
+				params: "<keyspace> <command> [<migration_uuid>]",
 				help: "Operates on online DDL (migrations). Examples:" +
 					" \nvtctl OnlineDDL test_keyspace show 82fa54ac_e83e_11ea_96b7_f875a4d24e90" +
 					" \nvtctl OnlineDDL test_keyspace show all" +
@@ -3224,8 +3224,7 @@ func commandApplySchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *fl
 	sqlFile := subFlags.String("sql-file", "", "Identifies the file that contains the SQL commands")
 	ddlStrategy := subFlags.String("ddl_strategy", string(schema.DDLStrategyDirect), "Online DDL strategy, compatible with @@ddl_strategy session variable (examples: 'gh-ost', 'pt-osc', 'gh-ost --max-load=Threads_running=100'")
 	uuidList := subFlags.String("uuid_list", "", "Optional: comma delimited explicit UUIDs for migration. If given, must match number of DDL changes")
-	migrationContext := subFlags.String("migration_context", "", "For Only DDL, optionally supply a custom unique string used as context for the migration(s) in this command. By default a unique context is auto-generated by Vitess")
-	requestContext := subFlags.String("request_context", "", "synonym for -migration_context")
+	requestContext := subFlags.String("request_context", "", "For Only DDL, optionally supply a custom unique string used as context for the migration(s) in this command. By default a unique context is auto-generated by Vitess")
 	waitReplicasTimeout := subFlags.Duration("wait_replicas_timeout", wrangler.DefaultWaitReplicasTimeout, "The amount of time to wait for replicas to receive the schema change via replication.")
 	skipPreflight := subFlags.Bool("skip_preflight", false, "Skip pre-apply schema checks, and directly forward schema change query to shards")
 	if err := subFlags.Parse(args); err != nil {
@@ -3244,15 +3243,10 @@ func commandApplySchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *fl
 	if err != nil {
 		return err
 	}
-	if *migrationContext == "" {
-		// -request_context is a legacy flag name
-		// we now prefer to use -migration_context, but we also keep backwards compatibility
-		*migrationContext = *requestContext
+	if *requestContext == "" {
+		*requestContext = fmt.Sprintf("vtctl:%s", executionUUID)
 	}
-	if *migrationContext == "" {
-		*migrationContext = fmt.Sprintf("vtctl:%s", executionUUID)
-	}
-	executor := schemamanager.NewTabletExecutor(*migrationContext, wr, *waitReplicasTimeout)
+	executor := schemamanager.NewTabletExecutor(*requestContext, wr, *waitReplicasTimeout)
 	if *allowLongUnavailability {
 		executor.AllowBigSchemaChange()
 	}
@@ -3274,7 +3268,6 @@ func commandApplySchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *fl
 }
 
 func commandOnlineDDL(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error {
-	json := subFlags.Bool("json", false, "Output JSON instead of human-readable table")
 	if err := subFlags.Parse(args); err != nil {
 		return err
 	}
@@ -3318,7 +3311,7 @@ func commandOnlineDDL(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag
 			}
 		}
 		query = fmt.Sprintf(`select
-				*
+				shard, mysql_schema, mysql_table, ddl_action, migration_uuid, strategy, started_timestamp, completed_timestamp, migration_status
 				from _vt.schema_migrations where %s`, condition)
 	case "retry":
 		if arg == "" {
@@ -3354,9 +3347,6 @@ func commandOnlineDDL(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag
 	if err != nil {
 		return err
 	}
-	if *json {
-		return printJSON(wr.Logger(), qr)
-	}
 	printQueryResult(loggerWriter{wr.Logger()}, qr)
 	return nil
 }
diff --git a/go/vt/vtctld/api.go b/go/vt/vtctld/api.go
index 6bd0021b38..314cac3f8a 100644
--- a/go/vt/vtctld/api.go
+++ b/go/vt/vtctld/api.go
@@ -633,8 +633,8 @@ func initAPI(ctx context.Context, ts *topo.Server, actions *ActionRepository, re
 		if err != nil {
 			return err
 		}
-		migrationContext := fmt.Sprintf("vtctld/api:%s", apiCallUUID)
-		executor := schemamanager.NewTabletExecutor(migrationContext, wr, time.Duration(req.ReplicaTimeoutSeconds)*time.Second)
+		requestContext := fmt.Sprintf("vtctld/api:%s", apiCallUUID)
+		executor := schemamanager.NewTabletExecutor(requestContext, wr, time.Duration(req.ReplicaTimeoutSeconds)*time.Second)
 
 		if err := executor.SetDDLStrategy(req.DDLStrategy); err != nil {
 			return fmt.Errorf("error setting DDL strategy: %v", err)
diff --git a/go/vt/vtctld/schema.go b/go/vt/vtctld/schema.go
index 6b9c559f80..ad57158cc7 100644
--- a/go/vt/vtctld/schema.go
+++ b/go/vt/vtctld/schema.go
@@ -130,7 +130,7 @@ func reviewMigrationRequest(ctx context.Context, ts *topo.Server, tmClient tmcli
 		"options":             sqltypes.StringBindVariable(onlineDDL.Options),
 		"ddl_action":          sqltypes.StringBindVariable(actionStr),
 		"requested_timestamp": sqltypes.Int64BindVariable(onlineDDL.RequestTimeSeconds()),
-		"migration_context":   sqltypes.StringBindVariable(onlineDDL.MigrationContext),
+		"migration_context":   sqltypes.StringBindVariable(onlineDDL.RequestContext),
 		"migration_status":    sqltypes.StringBindVariable(string(onlineDDL.Status)),
 	}
 
diff --git a/go/vt/vtgate/engine/delete.go b/go/vt/vtgate/engine/delete.go
index fb395788aa..74cf862e82 100644
--- a/go/vt/vtgate/engine/delete.go
+++ b/go/vt/vtgate/engine/delete.go
@@ -78,9 +78,7 @@ func (del *Delete) TryExecute(vcursor VCursor, bindVars map[string]*querypb.Bind
 	switch del.Opcode {
 	case Unsharded:
 		return del.execUnsharded(vcursor, bindVars, rss)
-	case Equal:
-		return del.execEqual(vcursor, bindVars, rss, del.deleteVindexEntries)
-	case IN, Scatter, ByDestination:
+	case Equal, IN, Scatter, ByDestination:
 		return del.execMultiDestination(vcursor, bindVars, rss, del.deleteVindexEntries)
 	default:
 		// Unreachable.
diff --git a/go/vt/vtgate/engine/dml.go b/go/vt/vtgate/engine/dml.go
index fe353ccdc4..0fcbb8690f 100644
--- a/go/vt/vtgate/engine/dml.go
+++ b/go/vt/vtgate/engine/dml.go
@@ -70,21 +70,10 @@ func (dml *DML) execUnsharded(vcursor VCursor, bindVars map[string]*querypb.Bind
 	return execShard(vcursor, dml.Query, bindVars, rss[0], true, true /* canAutocommit */)
 }
 
-func (dml *DML) execEqual(vcursor VCursor, bindVars map[string]*querypb.BindVariable, rss []*srvtopo.ResolvedShard, dmlSpecialFunc func(VCursor, map[string]*querypb.BindVariable, []*srvtopo.ResolvedShard) error) (*sqltypes.Result, error) {
+func (dml *DML) execMultiDestination(vcursor VCursor, bindVars map[string]*querypb.BindVariable, rss []*srvtopo.ResolvedShard, dmlSpecialFunc func(VCursor, map[string]*querypb.BindVariable, []*srvtopo.ResolvedShard) error) (*sqltypes.Result, error) {
 	if len(rss) == 0 {
 		return &sqltypes.Result{}, nil
 	}
-	if len(rss) != 1 {
-		return nil, fmt.Errorf("ResolveDestinations maps to %v shards", len(rss))
-	}
-	err := dmlSpecialFunc(vcursor, bindVars, rss)
-	if err != nil {
-		return nil, err
-	}
-	return execShard(vcursor, dml.Query, bindVars, rss[0], true /* rollbackOnError */, true /* canAutocommit */)
-}
-
-func (dml *DML) execMultiDestination(vcursor VCursor, bindVars map[string]*querypb.BindVariable, rss []*srvtopo.ResolvedShard, dmlSpecialFunc func(VCursor, map[string]*querypb.BindVariable, []*srvtopo.ResolvedShard) error) (*sqltypes.Result, error) {
 	err := dmlSpecialFunc(vcursor, bindVars, rss)
 	if err != nil {
 		return nil, err
diff --git a/go/vt/vtgate/engine/update.go b/go/vt/vtgate/engine/update.go
index dbb7a1829b..3a4552ce20 100644
--- a/go/vt/vtgate/engine/update.go
+++ b/go/vt/vtgate/engine/update.go
@@ -88,9 +88,7 @@ func (upd *Update) TryExecute(vcursor VCursor, bindVars map[string]*querypb.Bind
 	switch upd.Opcode {
 	case Unsharded:
 		return upd.execUnsharded(vcursor, bindVars, rss)
-	case Equal:
-		return upd.execEqual(vcursor, bindVars, rss, upd.updateVindexEntries)
-	case IN, Scatter, ByDestination:
+	case Equal, IN, Scatter, ByDestination:
 		return upd.execMultiDestination(vcursor, bindVars, rss, upd.updateVindexEntries)
 	default:
 		// Unreachable.
diff --git a/go/vt/vtgate/planbuilder/dml.go b/go/vt/vtgate/planbuilder/dml.go
index 2abc46f854..e1bcb05888 100644
--- a/go/vt/vtgate/planbuilder/dml.go
+++ b/go/vt/vtgate/planbuilder/dml.go
@@ -79,9 +79,6 @@ func getDMLRouting(where *sqlparser.Where, table *vindexes.Table) (
 	filters := sqlparser.SplitAndExpression(nil, where.Expr)
 	// go over the vindexes in the order of increasing cost
 	for _, colVindex := range table.Ordered {
-		if !colVindex.IsUnique() {
-			continue
-		}
 		if lu, isLu := colVindex.Vindex.(vindexes.LookupBackfill); isLu && lu.IsBackfilling() {
 			// Checking if the Vindex is currently backfilling or not, if it isn't we can read from the vindex table
 			// and we will be able to do a delete equal. Otherwise, we continue to look for next best vindex.
diff --git a/go/vt/vtgate/vindexes/consistent_lookup.go b/go/vt/vtgate/vindexes/consistent_lookup.go
index ea9dd14108..3706b78e69 100644
--- a/go/vt/vtgate/vindexes/consistent_lookup.go
+++ b/go/vt/vtgate/vindexes/consistent_lookup.go
@@ -100,7 +100,7 @@ func (lu *ConsistentLookup) Map(vcursor VCursor, ids []sqltypes.Value) ([]key.De
 		return out, nil
 	}
 
-	results, err := lu.lkp.Lookup(vcursor, ids, vtgatepb.CommitOrder_PRE)
+	results, err := lu.lkp.Lookup(vcursor, ids, vcursor.LookupRowLockShardSession())
 	if err != nil {
 		return nil, err
 	}
diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go
index 191dcbbc5a..d6ffdd474c 100644
--- a/go/vt/vttablet/onlineddl/executor.go
+++ b/go/vt/vttablet/onlineddl/executor.go
@@ -1478,17 +1478,17 @@ func (e *Executor) readMigration(ctx context.Context, uuid string) (onlineDDL *s
 		return nil, nil, ErrMigrationNotFound
 	}
 	onlineDDL = &schema.OnlineDDL{
-		Keyspace:         row["keyspace"].ToString(),
-		Table:            row["mysql_table"].ToString(),
-		Schema:           row["mysql_schema"].ToString(),
-		SQL:              row["migration_statement"].ToString(),
-		UUID:             row["migration_uuid"].ToString(),
-		Strategy:         schema.DDLStrategy(row["strategy"].ToString()),
-		Options:          row["options"].ToString(),
-		Status:           schema.OnlineDDLStatus(row["migration_status"].ToString()),
-		Retries:          row.AsInt64("retries", 0),
-		TabletAlias:      row["tablet"].ToString(),
-		MigrationContext: row["migration_context"].ToString(),
+		Keyspace:       row["keyspace"].ToString(),
+		Table:          row["mysql_table"].ToString(),
+		Schema:         row["mysql_schema"].ToString(),
+		SQL:            row["migration_statement"].ToString(),
+		UUID:           row["migration_uuid"].ToString(),
+		Strategy:       schema.DDLStrategy(row["strategy"].ToString()),
+		Options:        row["options"].ToString(),
+		Status:         schema.OnlineDDLStatus(row["migration_status"].ToString()),
+		Retries:        row.AsInt64("retries", 0),
+		TabletAlias:    row["tablet"].ToString(),
+		RequestContext: row["migration_context"].ToString(),
 	}
 	return onlineDDL, row, nil
 }
@@ -2020,13 +2020,13 @@ func (e *Executor) evaluateDeclarativeDiff(ctx context.Context, onlineDDL *schem
 // getCompletedMigrationByContextAndSQL chceks if there exists a completed migration with exact same
 // context and SQL as given migration. If so, it returns its UUID.
 func (e *Executor) getCompletedMigrationByContextAndSQL(ctx context.Context, onlineDDL *schema.OnlineDDL) (completedUUID string, err error) {
-	if onlineDDL.MigrationContext == "" {
+	if onlineDDL.RequestContext == "" {
 		// only applies to migrations with an explicit context
 		return "", nil
 	}
 	query, err := sqlparser.ParseAndBind(sqlSelectCompleteMigrationsByContextAndSQL,
 		sqltypes.StringBindVariable(e.keyspace),
-		sqltypes.StringBindVariable(onlineDDL.MigrationContext),
+		sqltypes.StringBindVariable(onlineDDL.RequestContext),
 		sqltypes.StringBindVariable(onlineDDL.SQL),
 	)
 	if err != nil {
@@ -2081,7 +2081,7 @@ func (e *Executor) executeMigration(ctx context.Context, onlineDDL *schema.Onlin
 		if completedUUID != "" {
 			// Yep. We mark this migration as implicitly complete, and we're done with it!
 			_ = e.onSchemaMigrationStatus(ctx, onlineDDL.UUID, schema.OnlineDDLStatusComplete, false, progressPctFull, etaSecondsNow, rowsCopiedUnknown)
-			_ = e.updateMigrationMessage(ctx, onlineDDL.UUID, fmt.Sprintf("duplicate DDL as %s for migration context %s", completedUUID, onlineDDL.MigrationContext))
+			_ = e.updateMigrationMessage(ctx, onlineDDL.UUID, fmt.Sprintf("duplicate DDL as %s for migration context %s", completedUUID, onlineDDL.RequestContext))
 			return nil
 		}
 	}
@@ -3230,7 +3230,7 @@ func (e *Executor) SubmitMigration(
 		sqltypes.StringBindVariable(string(onlineDDL.Strategy)),
 		sqltypes.StringBindVariable(onlineDDL.Options),
 		sqltypes.StringBindVariable(actionStr),
-		sqltypes.StringBindVariable(onlineDDL.MigrationContext),
+		sqltypes.StringBindVariable(onlineDDL.RequestContext),
 		sqltypes.StringBindVariable(string(schema.OnlineDDLStatusQueued)),
 		sqltypes.StringBindVariable(e.TabletAliasString()),
 		sqltypes.Int64BindVariable(retainArtifactsSeconds),
@@ -3268,8 +3268,8 @@ func (e *Executor) SubmitMigration(
 				if err != nil {
 					return nil, err
 				}
-				if pendingOnlineDDL.MigrationContext != onlineDDL.MigrationContext {
-					return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "singleton migration rejected: found pending migration: %s in different context: %s", pendingUUID, pendingOnlineDDL.MigrationContext)
+				if pendingOnlineDDL.RequestContext != onlineDDL.RequestContext {
+					return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "singleton migration rejected: found pending migration: %s in different context: %s", pendingUUID, pendingOnlineDDL.RequestContext)
 				}
 			}
 		}
diff --git a/go/vt/wrangler/traffic_switcher.go b/go/vt/wrangler/traffic_switcher.go
index 17e5b08507..fc71668330 100644
--- a/go/vt/wrangler/traffic_switcher.go
+++ b/go/vt/wrangler/traffic_switcher.go
@@ -1168,7 +1168,7 @@ func (ts *trafficSwitcher) createReverseVReplication(ctx context.Context) error
 					// We currently assume the primary vindex is the best way to filter, which may not be true.
 					inKeyrange = fmt.Sprintf(" where in_keyrange(%s, '%s.%s', '%s')", sqlparser.String(vtable.ColumnVindexes[0].Columns[0]), ts.SourceKeyspaceName(), vtable.ColumnVindexes[0].Name, key.KeyRangeString(source.GetShard().KeyRange))
 				}
-				filter = fmt.Sprintf("select * from %s%s", sqlescape.EscapeID(rule.Match), inKeyrange)
+				filter = fmt.Sprintf("select * from %s%s", rule.Match, inKeyrange)
 			}
 			reverseBls.Filter.Rules = append(reverseBls.Filter.Rules, &binlogdatapb.Rule{
 				Match:  rule.Match,
@@ -1456,24 +1456,20 @@ func getRenameFileName(tableName string) string {
 func (ts *trafficSwitcher) removeSourceTables(ctx context.Context, removalType workflow.TableRemovalType) error {
 	err := ts.ForAllSources(func(source *workflow.MigrationSource) error {
 		for _, tableName := range ts.Tables() {
-			query := fmt.Sprintf("drop table %s.%s",
-				sqlescape.EscapeID(sqlescape.UnescapeID(source.GetPrimary().DbName())),
-				sqlescape.EscapeID(sqlescape.UnescapeID(tableName)))
+			query := fmt.Sprintf("drop table %s.%s", source.GetPrimary().DbName(), tableName)
 			if removalType == workflow.DropTable {
-				ts.Logger().Infof("%s: Dropping table %s.%s\n",
-					source.GetPrimary().String(), source.GetPrimary().DbName(), tableName)
+				ts.Logger().Infof("Dropping table %s.%s\n", source.GetPrimary().DbName(), tableName)
 			} else {
 				renameName := getRenameFileName(tableName)
-				ts.Logger().Infof("%s: Renaming table %s.%s to %s.%s\n",
-					source.GetPrimary().String(), source.GetPrimary().DbName(), tableName, source.GetPrimary().DbName(), renameName)
+				ts.Logger().Infof("Renaming table %s.%s to %s.%s\n", source.GetPrimary().DbName(), tableName, source.GetPrimary().DbName(), renameName)
 				query = fmt.Sprintf("rename table %s.%s TO %s.%s", source.GetPrimary().DbName(), tableName, source.GetPrimary().DbName(), renameName)
 			}
 			_, err := ts.wr.ExecuteFetchAsDba(ctx, source.GetPrimary().Alias, query, 1, false, true)
 			if err != nil {
-				ts.Logger().Errorf("%s: Error removing table %s: %v", source.GetPrimary().String(), tableName, err)
+				ts.Logger().Errorf("Error removing table %s: %v", tableName, err)
 				return err
 			}
-			ts.Logger().Infof("%s: Removed table %s.%s\n", source.GetPrimary().String(), source.GetPrimary().DbName(), tableName)
+			ts.Logger().Infof("Removed table %s.%s\n", source.GetPrimary().DbName(), tableName)
 
 		}
 		return nil
@@ -1548,19 +1544,14 @@ func (ts *trafficSwitcher) removeTargetTables(ctx context.Context) error {
 	log.Infof("removeTargetTables")
 	err := ts.ForAllTargets(func(target *workflow.MigrationTarget) error {
 		for _, tableName := range ts.Tables() {
-			query := fmt.Sprintf("drop table %s.%s",
-				sqlescape.EscapeID(sqlescape.UnescapeID(target.GetPrimary().DbName())),
-				sqlescape.EscapeID(sqlescape.UnescapeID(tableName)))
-			ts.Logger().Infof("%s: Dropping table %s.%s\n",
-				target.GetPrimary().String(), target.GetPrimary().DbName(), tableName)
+			query := fmt.Sprintf("drop table %s.%s", target.GetPrimary().DbName(), tableName)
+			ts.Logger().Infof("Dropping table %s.%s\n", target.GetPrimary().DbName(), tableName)
 			_, err := ts.wr.ExecuteFetchAsDba(ctx, target.GetPrimary().Alias, query, 1, false, true)
 			if err != nil {
-				ts.Logger().Errorf("%s: Error removing table %s: %v",
-					target.GetPrimary().String(), tableName, err)
+				ts.Logger().Errorf("Error removing table %s: %v", tableName, err)
 				return err
 			}
-			ts.Logger().Infof("%s: Removed table %s.%s\n",
-				target.GetPrimary().String(), target.GetPrimary().DbName(), tableName)
+			ts.Logger().Infof("Removed table %s.%s\n", target.GetPrimary().DbName(), tableName)
 
 		}
 		return nil


Test patch:
diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml
deleted file mode 100644
index 742132759d..0000000000
--- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml
+++ /dev/null
@@ -1,171 +0,0 @@
-name: Upgrade Downgrade Testing - Backups - E2E
-on:
-  push:
-  pull_request:
-
-concurrency:
-  group: format('{0}-{1}', ${{ github.ref }}, 'Upgrade Downgrade Testing - Backups - E2E')
-  cancel-in-progress: true
-
-jobs:
-  get_upgrade_downgrade_label:
-    timeout-minutes: 10
-    if: github.repository == 'vitessio/vitess'
-    name: Get the Upgrade Downgrade pull request label
-    runs-on: ubuntu-latest
-    outputs:
-      hasLabel: ${{ steps.check_label.outputs.hasLabel }}
-
-    steps:
-      - name: Check Label for PR
-        if: github.event_name == 'pull_request'
-        uses: Dreamcodeio/pr-has-label-action@master
-        id: check_label
-        with:
-          label: Skip Upgrade Downgrade
-
-  get_latest_release:
-    timeout-minutes: 10
-    if: always() && (github.event_name != 'pull_request' || needs.get_upgrade_downgrade_label.outputs.hasLabel != 'true')
-    name: Get latest release
-    runs-on: ubuntu-latest
-    needs:
-      - get_upgrade_downgrade_label
-    outputs:
-      latest_release: ${{ steps.set-outpout.outputs.matrix }}
-
-    steps:
-      - name: Check out to HEAD
-        uses: actions/checkout@v2
-        with:
-          fetch-depth: 0
-
-      - name: Get latest major release of Vitess
-        run: |
-          last_major_releases=$(git show-ref --tags | grep -E 'refs/tags/v[0-9]*.[0-9]*.0$' | sed 's/[a-z0-9]* refs\/tags\/v//' | sort -nr | head -n1)
-          echo "latest_releases=$(echo "$last_major_releases" | awk ' BEGIN { ORS = ""; print "["; } { print "\/\@{\\\"project\\\":\\\"v"$0"\\\"}\/\@"; } END { print "]"; }' | sed "s^\/\@\/\@^, ^g;s^\/\@^^g")" >> $GITHUB_ENV
-
-      - name: Set output
-        id: set-outpout
-        run: |
-          echo "::set-output name=matrix::{\"include\":${{ env.latest_releases }} }"
-
-  upgrade_downgrade_test_e2e:
-    timeout-minutes: 60
-    if: always() && (github.event_name != 'pull_request' || needs.get_upgrade_downgrade_label.outputs.hasLabel != 'false')
-    name: Run Upgrade Downgrade Test
-    runs-on: ubuntu-18.04
-    needs:
-      - get_upgrade_downgrade_label
-      - get_latest_release
-    strategy:
-      fail-fast: false
-      matrix: ${{fromJSON(needs.get_latest_release.outputs.latest_release)}}
-
-    steps:
-    - name: Set up Go
-      uses: actions/setup-go@v2
-      with:
-        go-version: 1.17
-
-    - name: Set up python
-      uses: actions/setup-python@v2
-
-    - name: Tune the OS
-      run: |
-        echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range
-
-    - name: Check out commit's code
-      uses: actions/checkout@v2
-
-    - name: Get base dependencies
-      run: |
-        sudo apt-get update
-        sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata
-        sudo service mysql stop
-        sudo service etcd stop
-        sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
-        sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld
-        go mod download
-
-        # install JUnit report formatter
-        go get -u github.com/vitessio/go-junit-report@HEAD
-
-        wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
-        sudo apt-get install -y gnupg2
-        sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb
-        sudo apt-get update
-        sudo apt-get install percona-xtrabackup-24
-
-    # Checkout to the last release of Vitess
-    - name: Check out other version's code (${{ matrix.project }})
-      uses: actions/checkout@v2
-      with:
-        ref: ${{ matrix.project }}
-
-    - name: Get dependencies for the last release
-      run: |
-        go mod download
-
-    - name: Building last release's binaries
-      timeout-minutes: 10
-      run: |
-        source build.env
-        make build
-        mkdir -p /tmp/vitess-build-other/
-        cp -R bin /tmp/vitess-build-other/
-        rm -Rf bin/*
-
-    # Checkout to this build's commit
-    - name: Check out commit's code
-      uses: actions/checkout@v2
-
-    - name: Get dependencies for this commit
-      run: |
-        go mod download
-
-    - name: Building the binaries for this commit
-      timeout-minutes: 10
-      run: |
-        source build.env
-        make build
-        mkdir -p /tmp/vitess-build-current/
-        cp -R bin /tmp/vitess-build-current/
-
-    # Swap binaries, use last release's VTTablet
-    - name: Use last release's VTTablet
-      run: |
-        source build.env
-
-        rm -f $PWD/bin/vttablet
-        cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet
-        vttablet --version
-
-    # Run test with VTTablet at version N-1 and VTBackup at version N
-    - name: Run backups tests (vttablet=N-1, vtbackup=N)
-      run: |
-        rm -rf /tmp/vtdataroot
-        mkdir -p /tmp/vtdataroot
-        set -x
-        source build.env
-        eatmydata -- go run test.go -skip-build -docker=false -print-log -follow -tag upgrade_downgrade_backups
-
-    # Swap binaries again, use current version's VTTablet, and last release's VTBackup
-    - name: Use current version VTTablet, and other version VTBackup
-      run: |
-        source build.env
-
-        rm -f $PWD/bin/vtbackup $PWD/bin/vttablet
-        cp /tmp/vitess-build-current/bin/vtbackup $PWD/bin/vtbackup
-        cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet
-        vtbackup --version
-        vttablet --version
-
-    # Run test again with VTTablet at version N, and VTBackup at version N-1
-    - name: Run backups tests (vttablet=N, vtbackup=N-1)
-      run: |
-        rm -rf /tmp/vtdataroot
-        mkdir -p /tmp/vtdataroot
-        set -x
-        source build.env
-        eatmydata -- go run test.go -skip-build -keep-data -docker=false -print-log -follow -tag upgrade_downgrade_backups
diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual.yml b/.github/workflows/upgrade_downgrade_test_backups_manual.yml
deleted file mode 100644
index 9643dae7f7..0000000000
--- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml
+++ /dev/null
@@ -1,277 +0,0 @@
-name: Upgrade Downgrade Testing - Backups - Manual
-on:
-  push:
-  pull_request:
-
-concurrency:
-  group: format('{0}-{1}', ${{ github.ref }}, 'Upgrade Downgrade Testing - Backups - Manual')
-  cancel-in-progress: true
-
-jobs:
-  get_upgrade_downgrade_label:
-    timeout-minutes: 5
-    if: github.repository == 'vitessio/vitess'
-    name: Get the Upgrade Downgrade pull request label
-    runs-on: ubuntu-latest
-    outputs:
-      hasLabel: ${{ steps.check_label.outputs.hasLabel }}
-
-    steps:
-      - name: Check Label for PR
-        if: github.event_name == 'pull_request'
-        uses: Dreamcodeio/pr-has-label-action@master
-        id: check_label
-        with:
-          label: Skip Upgrade Downgrade
-
-  get_latest_release:
-    timeout-minutes: 5
-    if: always() && (github.event_name != 'pull_request' || needs.get_upgrade_downgrade_label.outputs.hasLabel != 'true')
-    name: Get latest release
-    runs-on: ubuntu-latest
-    needs:
-      - get_upgrade_downgrade_label
-    outputs:
-      latest_release: ${{ steps.set-outpout.outputs.matrix }}
-
-    steps:
-      - name: Check out to HEAD
-        uses: actions/checkout@v2
-        with:
-          fetch-depth: 0
-
-      - name: Get latest major release of Vitess
-        run: |
-          last_major_releases=$(git show-ref --tags | grep -E 'refs/tags/v[0-9]*.[0-9]*.0$' | sed 's/[a-z0-9]* refs\/tags\/v//' | sort -nr | head -n1)
-          echo "latest_releases=$(echo "$last_major_releases" | awk ' BEGIN { ORS = ""; print "["; } { print "\/\@{\\\"project\\\":\\\"v"$0"\\\"}\/\@"; } END { print "]"; }' | sed "s^\/\@\/\@^, ^g;s^\/\@^^g")" >> $GITHUB_ENV
-
-      - name: Set output
-        id: set-outpout
-        run: |
-          echo "::set-output name=matrix::{\"include\":${{ env.latest_releases }} }"
-
-  # This job usually execute in ± 20 minutes
-  upgrade_downgrade_test_manual:
-    timeout-minutes: 40
-    if: always() && (github.event_name != 'pull_request' || needs.get_upgrade_downgrade_label.outputs.hasLabel != 'false')
-    name: Run Upgrade Downgrade Test Backup Manual
-    runs-on: ubuntu-latest
-    needs:
-      - get_upgrade_downgrade_label
-      - get_latest_release
-    strategy:
-      fail-fast: false
-      matrix: ${{fromJSON(needs.get_latest_release.outputs.latest_release)}}
-
-    steps:
-    - name: Set up Go
-      uses: actions/setup-go@v2
-      with:
-        go-version: 1.17
-
-    - name: Set up python
-      uses: actions/setup-python@v2
-
-    - name: Tune the OS
-      run: |
-        echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range
-
-    # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185
-    - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file
-      run: |
-        echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts
-    # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED!
-
-    - name: Get base dependencies
-      run: |
-        sudo DEBIAN_FRONTEND="noninteractive" apt-get update
-        # Uninstall any previously installed MySQL first
-        sudo systemctl stop apparmor
-        sudo DEBIAN_FRONTEND="noninteractive" apt-get remove -y --purge mysql-server mysql-client mysql-common
-        sudo apt-get -y autoremove
-        sudo apt-get -y autoclean
-        sudo deluser mysql
-        sudo rm -rf /var/lib/mysql
-        sudo rm -rf /etc/mysql
-        # Install mysql80
-        sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 467B942D3A79BD29
-        wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.20-1_all.deb
-        echo mysql-apt-config mysql-apt-config/select-server select mysql-8.0 | sudo debconf-set-selections
-        sudo DEBIAN_FRONTEND="noninteractive" dpkg -i mysql-apt-config*
-        sudo apt-get update
-        sudo DEBIAN_FRONTEND="noninteractive" apt-get install -y mysql-server mysql-client
-        # Install everything else we need, and configure
-        sudo apt-get install -y make unzip g++ etcd curl git wget eatmydata grep
-        sudo service mysql stop
-        sudo service etcd stop
-        sudo bash -c "echo '/usr/sbin/mysqld { }' > /etc/apparmor.d/usr.sbin.mysqld" # https://bugs.launchpad.net/ubuntu/+source/mariadb-10.1/+bug/1806263
-        sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
-        sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld || echo "could not remove mysqld profile"
-
-        # install JUnit report formatter
-        go get -u github.com/vitessio/go-junit-report@HEAD
-
-        wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
-        sudo apt-get install -y gnupg2
-        sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb
-        sudo apt-get update
-        sudo apt-get install percona-xtrabackup-24
-
-    # Checkout to the last release of Vitess
-    - name: Checkout to the other version's code (${{ matrix.project }})
-      uses: actions/checkout@v2
-      with:
-        ref: ${{ matrix.project }}
-
-    - name: Get dependencies for the last release
-      run: |
-        go mod download
-
-    - name: Building last release's binaries
-      timeout-minutes: 5
-      run: |
-        source build.env
-        make build
-        mkdir -p /tmp/vitess-build-other/
-        cp -R bin /tmp/vitess-build-other/
-        rm -Rf bin/*
-
-    # Checkout to this build's commit
-    - name: Checkout to commit's code
-      uses: actions/checkout@v2
-
-    - name: Get dependencies for this commit
-      run: |
-        go mod download
-
-    - name: Run make minimaltools
-      run: |
-        make minimaltools
-
-    - name: Building the binaries for this commit
-      timeout-minutes: 5
-      run: |
-        source build.env
-        make build
-        mkdir -p /tmp/vitess-build-current/
-        cp -R bin /tmp/vitess-build-current/
-
-    # We create a sharded Vitess cluster following the local example.
-    # We also insert a few rows in our three tables.
-    - name: Create the example Vitess cluster with all components using version N
-      timeout-minutes: 5
-      run: |
-        source build.env ; cd examples/local
-        ./backups/start_cluster.sh
-
-    # Taking a backup
-    - name: Take a backup of all the shards
-      timeout-minutes: 2
-      run: |
-        source build.env ; cd examples/local
-        ./backups/take_backups.sh
-
-    # We insert more data in every table after the backup.
-    # When we restore the backup made in the previous step, we do not want to see the rows we are about to insert now.
-    # The initial number of rows for each table is:
-    #     - customer: 5
-    #     - product:  2
-    #     - corder:   5
-    # We shall see the same number of rows after restoring the backup.
-    - name: Insert more data after the backup
-      run: |
-        source build.env ; cd examples/local ; source ./env.sh
-
-        echo "insert into customer(email) values('new_user_1@domain.com');" | mysql
-        echo "insert into product(sku, description, price) values('SKU-1009', 'description', 89);" | mysql
-        echo "insert into corder(customer_id, sku, price) values(1, 'SKU-1009', 100);" | mysql
-
-    # Stop all the tablets and remove their data
-    - name: Stop tablets
-      timeout-minutes: 5
-      run: |
-        source build.env ; cd examples/local
-        ./backups/stop_tablets.sh
-
-    # We downgrade: we use the version N-1 of vttablet
-    - name: Downgrade - Swap binaries, use VTTablet N-1
-      run: |
-        source build.env
-
-        rm -f $PWD/bin/vttablet
-        cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet
-        vttablet --version
-
-    # Starting the tablets again, they will automatically start restoring the last backup.
-    - name: Start new tablets and restore
-      timeout-minutes: 5
-      run: |
-        source build.env ; cd examples/local
-        ./backups/restart_tablets.sh
-        # give enough time to the tablets to restore the backup
-        sleep 60
-
-    # Count the number of rows in each table to make sure the restoration is successful.
-    - name: Assert the number of rows in every table
-      run: |
-        source build.env ; cd examples/local ; source ./env.sh
-
-        echo "select count(sku) from product;" | mysql 2>&1| grep 2
-        echo "select count(email) from customer;" | mysql 2>&1| grep 5
-        echo "select count(sku) from corder;" | mysql 2>&1| grep 5
-
-    # We insert one more row in every table.
-    - name: Insert more rows in the tables
-      run: |
-        source build.env ; cd examples/local ; source ./env.sh
-
-        echo "insert into customer(email) values('new_user_2@domain.com');" | mysql
-        echo "insert into product(sku, description, price) values('SKU-1011', 'description', 111);" | mysql
-        echo "insert into corder(customer_id, sku, price) values(1, 'SKU-1011', 111);" | mysql
-
-    # Taking a second backup of the cluster.
-    - name: Take a second backup of all the shards
-      timeout-minutes: 2
-      run: |
-        source build.env ; cd examples/local
-        ./backups/take_backups.sh
-
-    # Stopping the tablets so we can perform the upgrade.
-    - name: Stop tablets
-      timeout-minutes: 5
-      run: |
-        source build.env ; cd examples/local
-        ./backups/stop_tablets.sh
-
-    # We upgrade: we swap binaries and use the version N of the tablet.
-    - name: Upgrade - Swap binaries, use VTTablet N
-      run: |
-        source build.env
-
-        rm -f $PWD/bin/vttablet
-        cp /tmp/vitess-build-current/bin/vttablet $PWD/bin/vttablet
-        vttablet --version
-
-    # Starting the tablets again and restoring the previous backup.
-    - name: Start new tablets and restore
-      timeout-minutes: 5
-      run: |
-        source build.env ; cd examples/local
-        ./backups/restart_tablets.sh
-        # give enough time to the tablets to restore the backup
-        sleep 60
-
-    # We count the number of rows in every table to check that the restore step was successful.
-    - name: Assert the number of rows in every table
-      run: |
-        source build.env ; cd examples/local ; source ./env.sh
-
-        echo "select count(sku) from product;" | mysql 2>&1| grep 3
-        echo "select count(email) from customer;" | mysql 2>&1| grep 6
-        echo "select count(sku) from corder;" | mysql 2>&1| grep 6
-
-    - name: Stop the Vitess cluster
-      if: always()
-      run: |
-        source build.env ; cd examples/local
-        ./401_teardown.sh || true
\ No newline at end of file
diff --git a/go/mysql/client_test.go b/go/mysql/client_test.go
index 7978ee92b9..70872f909a 100644
--- a/go/mysql/client_test.go
+++ b/go/mysql/client_test.go
@@ -40,13 +40,25 @@ import (
 func assertSQLError(t *testing.T, err error, code int, sqlState string, subtext string, query string) {
 	t.Helper()
 
-	require.Error(t, err, "was expecting SQLError %v / %v / %v but got no error.", code, sqlState, subtext)
+	if err == nil {
+		t.Fatalf("was expecting SQLError %v / %v / %v but got no error.", code, sqlState, subtext)
+	}
 	serr, ok := err.(*SQLError)
-	require.True(t, ok, "was expecting SQLError %v / %v / %v but got: %v", code, sqlState, subtext, err)
-	require.Equal(t, code, serr.Num, "was expecting SQLError %v / %v / %v but got code %v", code, sqlState, subtext, serr.Num)
-	require.Equal(t, sqlState, serr.State, "was expecting SQLError %v / %v / %v but got state %v", code, sqlState, subtext, serr.State)
-	require.True(t, subtext == "" || strings.Contains(serr.Message, subtext), "was expecting SQLError %v / %v / %v but got message %v", code, sqlState, subtext, serr.Message)
-	require.Equal(t, query, serr.Query, "was expecting SQLError %v / %v / %v with Query '%v' but got query '%v'", code, sqlState, subtext, query, serr.Query)
+	if !ok {
+		t.Fatalf("was expecting SQLError %v / %v / %v but got: %v", code, sqlState, subtext, err)
+	}
+	if serr.Num != code {
+		t.Fatalf("was expecting SQLError %v / %v / %v but got code %v", code, sqlState, subtext, serr.Num)
+	}
+	if serr.State != sqlState {
+		t.Fatalf("was expecting SQLError %v / %v / %v but got state %v", code, sqlState, subtext, serr.State)
+	}
+	if subtext != "" && !strings.Contains(serr.Message, subtext) {
+		t.Fatalf("was expecting SQLError %v / %v / %v but got message %v", code, sqlState, subtext, serr.Message)
+	}
+	if serr.Query != query {
+		t.Fatalf("was expecting SQLError %v / %v / %v with Query '%v' but got query '%v'", code, sqlState, subtext, query, serr.Query)
+	}
 }
 
 // TestConnectTimeout runs connection failure scenarios against a
@@ -56,7 +68,9 @@ func TestConnectTimeout(t *testing.T) {
 	// Create a socket, but it's not accepting. So all Dial
 	// attempts will timeout.
 	listener, err := net.Listen("tcp", "127.0.0.1:")
-	require.NoError(t, err, "cannot listen: %v", err)
+	if err != nil {
+		t.Fatalf("cannot listen: %v", err)
+	}
 	host, port := getHostPort(t, listener.Addr())
 	params := &ConnParams{
 		Host: host,
@@ -69,7 +83,9 @@ func TestConnectTimeout(t *testing.T) {
 	done := make(chan struct{})
 	go func() {
 		_, err := Connect(ctx, params)
-		assert.Equal(t, context.Canceled, err, "Was expecting context.Canceled but got: %v", err)
+		if err != context.Canceled {
+			t.Errorf("Was expecting context.Canceled but got: %v", err)
+		}
 		close(done)
 	}()
 	time.Sleep(100 * time.Millisecond)
@@ -80,7 +96,9 @@ func TestConnectTimeout(t *testing.T) {
 	ctx, cancel = context.WithTimeout(context.Background(), 100*time.Millisecond)
 	_, err = Connect(ctx, params)
 	cancel()
-	assert.Equal(t, context.DeadlineExceeded, err, "Was expecting context.DeadlineExceeded but got: %v", err)
+	if err != context.DeadlineExceeded {
+		t.Errorf("Was expecting context.DeadlineExceeded but got: %v", err)
+	}
 
 	// Tests a connection timeout through params
 	ctx = context.Background()
@@ -88,7 +106,9 @@ func TestConnectTimeout(t *testing.T) {
 	paramsWithTimeout.ConnectTimeoutMs = 1
 	_, err = Connect(ctx, &paramsWithTimeout)
 	cancel()
-	assert.Equal(t, context.DeadlineExceeded, err, "Was expecting context.DeadlineExceeded but got: %v", err)
+	if err != context.DeadlineExceeded {
+		t.Errorf("Was expecting context.DeadlineExceeded but got: %v", err)
+	}
 
 	// Now the server will listen, but close all connections on accept.
 	wg := sync.WaitGroup{}
@@ -119,7 +139,9 @@ func TestConnectTimeout(t *testing.T) {
 	// properly returns the right error. To simulate exactly the
 	// right failure, try to dial a Unix socket that's just a temp file.
 	fd, err := os.CreateTemp("", "mysql")
-	require.NoError(t, err, "cannot create TempFile: %v", err)
+	if err != nil {
+		t.Fatalf("cannot create TemFile: %v", err)
+	}
 	name := fd.Name()
 	fd.Close()
 	params.UnixSocket = name
diff --git a/go/test/endtoend/cluster/vtctlclient_process.go b/go/test/endtoend/cluster/vtctlclient_process.go
index 91aaadd219..f3124d3e8a 100644
--- a/go/test/endtoend/cluster/vtctlclient_process.go
+++ b/go/test/endtoend/cluster/vtctlclient_process.go
@@ -38,10 +38,10 @@ type VtctlClientProcess struct {
 
 // VtctlClientParams encapsulated params to provide if non-default
 type VtctlClientParams struct {
-	DDLStrategy      string
-	MigrationContext string
-	SkipPreflight    bool
-	UUIDList         string
+	DDLStrategy    string
+	RequestContext string
+	SkipPreflight  bool
+	UUIDList       string
 }
 
 // InitShardPrimary executes vtctlclient command to make specified tablet the primary for the shard.
@@ -76,8 +76,8 @@ func (vtctlclient *VtctlClientProcess) ApplySchemaWithOutput(Keyspace string, SQ
 		"ApplySchema",
 		"-sql", SQL,
 	}
-	if params.MigrationContext != "" {
-		args = append(args, "-migration_context", params.MigrationContext)
+	if params.RequestContext != "" {
+		args = append(args, "-request_context", params.RequestContext)
 	}
 	if params.DDLStrategy != "" {
 		args = append(args, "-ddl_strategy", params.DDLStrategy)
diff --git a/go/test/endtoend/onlineddl/declarative/onlineddl_declarative_test.go b/go/test/endtoend/onlineddl/declarative/onlineddl_declarative_test.go
index 87a0327626..9cc1a0e978 100644
--- a/go/test/endtoend/onlineddl/declarative/onlineddl_declarative_test.go
+++ b/go/test/endtoend/onlineddl/declarative/onlineddl_declarative_test.go
@@ -90,7 +90,7 @@ var (
 	cell                  = "zone1"
 	schemaChangeDirectory = ""
 	tableName             = `stress_test`
-	migrationContext      = "1111-2222-3333"
+	requestContext        = "1111-2222-3333"
 	createStatement1      = `
 		CREATE TABLE stress_test (
 			id bigint(20) not null,
@@ -511,7 +511,7 @@ func testOnlineDDLStatement(t *testing.T, alterStatement string, ddlStrategy str
 			uuid = row.AsString("uuid", "")
 		}
 	} else {
-		output, err := clusterInstance.VtctlclientProcess.ApplySchemaWithOutput(keyspaceName, alterStatement, cluster.VtctlClientParams{DDLStrategy: ddlStrategy, MigrationContext: migrationContext, SkipPreflight: true})
+		output, err := clusterInstance.VtctlclientProcess.ApplySchemaWithOutput(keyspaceName, alterStatement, cluster.VtctlClientParams{DDLStrategy: ddlStrategy, RequestContext: requestContext, SkipPreflight: true})
 		if expectError == "" {
 			assert.NoError(t, err)
 			uuid = output
diff --git a/go/test/endtoend/vreplication/config.go b/go/test/endtoend/vreplication/config.go
index 09dbd7460a..4e3add0c5b 100644
--- a/go/test/endtoend/vreplication/config.go
+++ b/go/test/endtoend/vreplication/config.go
@@ -1,12 +1,12 @@
 package vreplication
 
-// The product, customer, Lead, Lead-1 tables are used to exercise and test most Workflow variants.
+// The product, customer, and Lead tables are used to exercise and test most Workflow variants.
 // We violate the NO_ZERO_DATES and NO_ZERO_IN_DATE sql_modes that are enabled by default in
 // MySQL 5.7+ and MariaDB 10.2+ to ensure that vreplication still works everywhere and the
 // permissive sql_mode now used in vreplication causes no unwanted side effects.
-// The Lead and Lead-1 tables also allows us to test several things:
+// The Lead table also allows us to test several things:
 //   1. Mixed case identifiers
-//   2. Column and table names with special characters in them, namely a dash
+//   2. Column names with special characters in them, namely a dash
 //   3. Identifiers using reserved words, as lead is a reserved word in MySQL 8.0+ (https://dev.mysql.com/doc/refman/8.0/en/keywords.html)
 var (
 	initialProductSchema = `
@@ -20,7 +20,6 @@ create table order_seq(id int, next_id bigint, cache bigint, primary key(id)) co
 create table customer2(cid int, name varbinary(128), typ enum('individual','soho','enterprise'), sport set('football','cricket','baseball'),ts timestamp not null default current_timestamp, primary key(cid));
 create table customer_seq2(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence';
 create table ` + "`Lead`(`Lead-id`" + ` binary(16), name varbinary(16), date1 datetime not null default '0000-00-00 00:00:00', date2 datetime not null default '2021-00-01 00:00:00', primary key (` + "`Lead-id`" + `));
-create table ` + "`Lead-1`(`Lead`" + ` binary(16), name varbinary(16), date1 datetime not null default '0000-00-00 00:00:00', date2 datetime not null default '2021-00-01 00:00:00', primary key (` + "`Lead`" + `));
 `
 
 	initialProductVSchema = `
@@ -40,8 +39,7 @@ create table ` + "`Lead-1`(`Lead`" + ` binary(16), name varbinary(16), date1 dat
 	"order_seq": {
 		"type": "sequence"
 	},
-	"Lead": {},
-	"Lead-1": {}
+	"Lead": {}
   }
 }
 `
@@ -88,14 +86,6 @@ create table ` + "`Lead-1`(`Lead`" + ` binary(16), name varbinary(16), date1 dat
 	          "column": "Lead-id",
 	          "name": "bmd5"
 	        }
-	      ]
-		},
-	  "Lead-1": {
-          "column_vindexes": [
-	        {
-	          "column": "Lead",
-	          "name": "bmd5"
-	        }
 	      ]
 		}
    }
diff --git a/go/test/endtoend/vreplication/resharding_workflows_v2_test.go b/go/test/endtoend/vreplication/resharding_workflows_v2_test.go
index 4641081d37..cf8b0feaee 100644
--- a/go/test/endtoend/vreplication/resharding_workflows_v2_test.go
+++ b/go/test/endtoend/vreplication/resharding_workflows_v2_test.go
@@ -396,7 +396,7 @@ func testMoveTablesV2Workflow(t *testing.T) {
 
 	testVSchemaForSequenceAfterMoveTables(t)
 
-	createMoveTablesWorkflow(t, "Lead,Lead-1")
+	createMoveTablesWorkflow(t, "Lead")
 	output, _ = vc.VtctlClient.ExecuteCommandWithOutput(listAllArgs...)
 	require.Contains(t, output, "Following workflow(s) found in keyspace customer: wf1")
 
diff --git a/go/test/endtoend/vreplication/vreplication_test.go b/go/test/endtoend/vreplication/vreplication_test.go
index 3dba2ca50c..622f9d85bf 100644
--- a/go/test/endtoend/vreplication/vreplication_test.go
+++ b/go/test/endtoend/vreplication/vreplication_test.go
@@ -124,9 +124,9 @@ func TestBasicVreplicationWorkflow(t *testing.T) {
 	materializeRollup(t)
 	shardCustomer(t, true, []*Cell{defaultCell}, defaultCellName, false)
 
-	// the Lead and Lead-1 tables tested a specific case with binary sharding keys. Drop it now so that we don't
+	// the Lead table was to test a specific case with binary sharding keys. Drop it now so that we don't
 	// have to update the rest of the tests
-	execVtgateQuery(t, vtgateConn, "customer", "drop table `Lead`,`Lead-1`")
+	execVtgateQuery(t, vtgateConn, "customer", "drop table `Lead`")
 	validateRollupReplicates(t)
 	shardOrders(t)
 	shardMerchant(t)
@@ -344,7 +344,7 @@ func shardCustomer(t *testing.T, testReverse bool, cells []*Cell, sourceCellOrAl
 		defaultCell := cells[0]
 		custKs := vc.Cells[defaultCell.Name].Keyspaces["customer"]
 
-		tables := "customer,Lead,Lead-1"
+		tables := "customer,Lead"
 		moveTables(t, sourceCellOrAlias, workflow, sourceKs, targetKs, tables)
 
 		customerTab1 := custKs.Shards["-80"].Tablets["zone1-200"].Vttablet
@@ -361,15 +361,12 @@ func shardCustomer(t *testing.T, testReverse bool, cells []*Cell, sourceCellOrAl
 		require.True(t, validateThatQueryExecutesOnTablet(t, vtgateConn, productTab, "product", insertQuery1, matchInsertQuery1))
 
 		// confirm that the backticking of table names in the routing rules works
-		tbls := []string{"Lead", "Lead-1"}
-		for _, tbl := range tbls {
-			output, err := osExec(t, "mysql", []string{"-u", "vtdba", "-P", fmt.Sprintf("%d", vc.ClusterConfig.vtgateMySQLPort),
-				"--host=127.0.0.1", "-e", fmt.Sprintf("select * from `%s`", tbl)})
-			if err != nil {
-				require.FailNow(t, output)
-			}
-			execVtgateQuery(t, vtgateConn, "product", fmt.Sprintf("update `%s` set name='xyz'", tbl))
+		output, err := osExec(t, "mysql", []string{"-u", "vtdba", "-P", fmt.Sprintf("%d", vc.ClusterConfig.vtgateMySQLPort),
+			"--host=127.0.0.1", "-e", "select * from Lead"})
+		if err != nil {
+			require.FailNow(t, output)
 		}
+		execVtgateQuery(t, vtgateConn, "product", "update Lead set name='xyz'")
 
 		vdiff(t, ksWorkflow, "")
 		switchReadsDryRun(t, allCellNames, ksWorkflow, dryRunResultsReadCustomerShard)
diff --git a/go/test/endtoend/vreplication/vreplication_test_env.go b/go/test/endtoend/vreplication/vreplication_test_env.go
index db01f4e2f0..edef3dc314 100644
--- a/go/test/endtoend/vreplication/vreplication_test_env.go
+++ b/go/test/endtoend/vreplication/vreplication_test_env.go
@@ -19,14 +19,14 @@ package vreplication
 var dryRunResultsSwitchWritesCustomerShard = []string{
 	"Lock keyspace product",
 	"Lock keyspace customer",
-	"Stop writes on keyspace product, tables [Lead,Lead-1,customer]:",
+	"Stop writes on keyspace product, tables [Lead,customer]:",
 	"/       Keyspace product, Shard 0 at Position",
 	"Wait for VReplication on stopped streams to catchup for upto 30s",
 	"Create reverse replication workflow p2c_reverse",
 	"Create journal entries on source databases",
-	"Enable writes on keyspace customer tables [Lead,Lead-1,customer]",
+	"Enable writes on keyspace customer tables [Lead,customer]",
 	"Switch routing from keyspace product to keyspace customer",
-	"Routing rules for tables [Lead,Lead-1,customer] will be updated",
+	"Routing rules for tables [Lead,customer] will be updated",
 	"SwitchWrites completed, freeze and delete vreplication streams on:",
 	"       tablet 200 ",
 	"       tablet 300 ",
@@ -41,8 +41,8 @@ var dryRunResultsSwitchWritesCustomerShard = []string{
 
 var dryRunResultsReadCustomerShard = []string{
 	"Lock keyspace product",
-	"Switch reads for tables [Lead,Lead-1,customer] to keyspace customer for tablet types [REPLICA,RDONLY]",
-	"Routing rules for tables [Lead,Lead-1,customer] will be updated",
+	"Switch reads for tables [Lead,customer] to keyspace customer for tablet types [REPLICA,RDONLY]",
+	"Routing rules for tables [Lead,customer] will be updated",
 	"Unlock keyspace product",
 }
 
@@ -91,9 +91,8 @@ var dryRunResultsDropSourcesDropCustomerShard = []string{
 	"Lock keyspace customer",
 	"Dropping these tables from the database and removing them from the vschema for keyspace product:",
 	"	Keyspace product Shard 0 DbName vt_product Tablet 100 Table Lead",
-	"	Keyspace product Shard 0 DbName vt_product Tablet 100 Table Lead-1",
 	"	Keyspace product Shard 0 DbName vt_product Tablet 100 Table customer",
-	"Denied tables [Lead,Lead-1,customer] will be removed from:",
+	"Denied tables [Lead,customer] will be removed from:",
 	"	Keyspace product Shard 0 Tablet 100",
 	"Delete reverse vreplication streams on source:",
 	"	Keyspace product Shard 0 Workflow p2c_reverse DbName vt_product Tablet 100",
@@ -110,9 +109,8 @@ var dryRunResultsDropSourcesRenameCustomerShard = []string{
 	"Lock keyspace customer",
 	"Renaming these tables from the database and removing them from the vschema for keyspace product:",
 	"	Keyspace product Shard 0 DbName vt_product Tablet 100 Table Lead",
-	"	Keyspace product Shard 0 DbName vt_product Tablet 100 Table Lead-1",
 	"	Keyspace product Shard 0 DbName vt_product Tablet 100 Table customer",
-	"Denied tables [Lead,Lead-1,customer] will be removed from:",
+	"Denied tables [Lead,customer] will be removed from:",
 	"	Keyspace product Shard 0 Tablet 100",
 	"Delete reverse vreplication streams on source:",
 	"	Keyspace product Shard 0 Workflow p2c_reverse DbName vt_product Tablet 100",
diff --git a/go/test/endtoend/vtgate/gen4/gen4_test.go b/go/test/endtoend/vtgate/gen4/gen4_test.go
index 5d90dc8b5b..07a4f4b5e8 100644
--- a/go/test/endtoend/vtgate/gen4/gen4_test.go
+++ b/go/test/endtoend/vtgate/gen4/gen4_test.go
@@ -362,7 +362,6 @@ func TestSubShardVindex(t *testing.T) {
 		exp:      `[[INT64(109) VARBINARY("28") VARCHAR("28") VARCHAR("shard-20c0-")]]`,
 	}}
 
-	defer utils.ExecAllowError(t, conn, `delete from multicol_tbl`)
 	uid := 1
 	// insert data in all shards to know where the query fan-out
 	for _, s := range shardedKsShards {
@@ -377,6 +376,7 @@ func TestSubShardVindex(t *testing.T) {
 	require.NoError(t, err)
 	defer newConn.Close()
 
+	defer utils.ExecAllowError(t, newConn, `delete from multicol_tbl`)
 	for _, workload := range []string{"olap", "oltp"} {
 		utils.Exec(t, newConn, fmt.Sprintf(`set workload = %s`, workload))
 		for _, tcase := range tcases {
@@ -387,3 +387,59 @@ func TestSubShardVindex(t *testing.T) {
 		}
 	}
 }
+
+func TestSubShardVindexDML(t *testing.T) {
+	ctx := context.Background()
+	conn, err := mysql.Connect(ctx, &vtParams)
+	require.NoError(t, err)
+	defer conn.Close()
+
+	tcases := []struct {
+		regionID       int
+		shardsAffected int
+	}{{
+		regionID:       140, // shard--19a0
+		shardsAffected: 1,
+	}, {
+		regionID:       412, // shard--19a0 and shard-19a0-20
+		shardsAffected: 2,
+	}, {
+		regionID:       24, // shard-19a0-20
+		shardsAffected: 1,
+	}, {
+		regionID:       89, // shard-20-20c0 and shard-20c0-
+		shardsAffected: 2,
+	}, {
+		regionID:       109, // shard-20c0-
+		shardsAffected: 1,
+	}}
+
+	uid := 1
+	// insert data in all shards to know where the query fan-out
+	for _, s := range shardedKsShards {
+		utils.Exec(t, conn, fmt.Sprintf("use `%s:%s`", shardedKs, s))
+		for _, tcase := range tcases {
+			utils.Exec(t, conn, fmt.Sprintf("insert into multicol_tbl(cola,colb,colc,msg) values(%d,_binary '%d','%d','shard-%s')", tcase.regionID, uid, uid, s))
+			uid++
+		}
+	}
+
+	newConn, err := mysql.Connect(ctx, &vtParams)
+	require.NoError(t, err)
+	defer newConn.Close()
+
+	defer utils.ExecAllowError(t, newConn, `delete from multicol_tbl`)
+	for _, tcase := range tcases {
+		t.Run(strconv.Itoa(tcase.regionID), func(t *testing.T) {
+			qr := utils.Exec(t, newConn, fmt.Sprintf("update multicol_tbl set msg = 'bar' where cola = %d", tcase.regionID))
+			assert.EqualValues(t, tcase.shardsAffected, qr.RowsAffected)
+		})
+	}
+
+	for _, tcase := range tcases {
+		t.Run(strconv.Itoa(tcase.regionID), func(t *testing.T) {
+			qr := utils.Exec(t, newConn, fmt.Sprintf("delete from multicol_tbl where cola = %d", tcase.regionID))
+			assert.EqualValues(t, tcase.shardsAffected, qr.RowsAffected)
+		})
+	}
+}
diff --git a/go/vt/schema/online_ddl_test.go b/go/vt/schema/online_ddl_test.go
index bb029617e8..4b9387ac5b 100644
--- a/go/vt/schema/online_ddl_test.go
+++ b/go/vt/schema/online_ddl_test.go
@@ -343,7 +343,7 @@ func TestOnlineDDLFromCommentedStatement(t *testing.T) {
 			require.NoError(t, err)
 			assert.True(t, IsOnlineDDLUUID(o2.UUID))
 			assert.Equal(t, o1.UUID, o2.UUID)
-			assert.Equal(t, migrationContext, o2.MigrationContext)
+			assert.Equal(t, migrationContext, o2.RequestContext)
 			assert.Equal(t, "t", o2.Table)
 			assert.Equal(t, strategySetting.Strategy, o2.Strategy)
 			assert.Equal(t, strategySetting.Options, o2.Options)
diff --git a/go/vt/vtgate/engine/delete_test.go b/go/vt/vtgate/engine/delete_test.go
index 1327dab2af..43bd090234 100644
--- a/go/vt/vtgate/engine/delete_test.go
+++ b/go/vt/vtgate/engine/delete_test.go
@@ -541,3 +541,40 @@ func TestDeleteInChangedVindexMultiCol(t *testing.T) {
 		`ExecuteMultiShard sharded.-20: dummy_update {} true true`,
 	})
 }
+
+func TestDeleteEqualSubshard(t *testing.T) {
+	vindex, _ := vindexes.NewRegionExperimental("", map[string]string{"region_bytes": "1"})
+	del := &Delete{
+		DML: &DML{
+			RoutingParameters: &RoutingParameters{
+				Opcode: Equal,
+				Keyspace: &vindexes.Keyspace{
+					Name:    "ks",
+					Sharded: true,
+				},
+				Vindex: vindex,
+				Values: []evalengine.Expr{evalengine.NewLiteralInt(1)},
+			},
+			Query: "dummy_delete",
+		},
+	}
+
+	vc := newDMLTestVCursor("-20", "20-")
+	vc.shardForKsid = []string{"-20", "20-"}
+	_, err := del.TryExecute(vc, map[string]*querypb.BindVariable{}, false)
+	require.NoError(t, err)
+	vc.ExpectLog(t, []string{
+		`ResolveDestinationsMultiCol ks [[INT64(1)]] Destinations:DestinationKeyRange(01-02)`,
+		`ExecuteMultiShard ks.-20: dummy_delete {} ks.20-: dummy_delete {} true false`,
+	})
+
+	vc.Rewind()
+	// as it is single shard so autocommit should be allowed.
+	vc.shardForKsid = []string{"-20"}
+	_, err = del.TryExecute(vc, map[string]*querypb.BindVariable{}, false)
+	require.NoError(t, err)
+	vc.ExpectLog(t, []string{
+		`ResolveDestinationsMultiCol ks [[INT64(1)]] Destinations:DestinationKeyRange(01-02)`,
+		`ExecuteMultiShard ks.-20: dummy_delete {} true true`,
+	})
+}
diff --git a/go/vt/vtgate/engine/update_test.go b/go/vt/vtgate/engine/update_test.go
index 9ba088d649..11b8e6bd11 100644
--- a/go/vt/vtgate/engine/update_test.go
+++ b/go/vt/vtgate/engine/update_test.go
@@ -879,6 +879,43 @@ func TestUpdateInChangedVindexMultiCol(t *testing.T) {
 	})
 }
 
+func TestUpdateEqualSubshard(t *testing.T) {
+	vindex, _ := vindexes.NewRegionExperimental("", map[string]string{"region_bytes": "1"})
+	upd := &Update{
+		DML: &DML{
+			RoutingParameters: &RoutingParameters{
+				Opcode: Equal,
+				Keyspace: &vindexes.Keyspace{
+					Name:    "ks",
+					Sharded: true,
+				},
+				Vindex: vindex,
+				Values: []evalengine.Expr{evalengine.NewLiteralInt(1)},
+			},
+			Query: "dummy_update",
+		},
+	}
+
+	vc := newDMLTestVCursor("-20", "20-")
+	vc.shardForKsid = []string{"-20", "20-"}
+	_, err := upd.TryExecute(vc, map[string]*querypb.BindVariable{}, false)
+	require.NoError(t, err)
+	vc.ExpectLog(t, []string{
+		`ResolveDestinationsMultiCol ks [[INT64(1)]] Destinations:DestinationKeyRange(01-02)`,
+		`ExecuteMultiShard ks.-20: dummy_update {} ks.20-: dummy_update {} true false`,
+	})
+
+	vc.Rewind()
+	// as it is single shard so autocommit should be allowed.
+	vc.shardForKsid = []string{"-20"}
+	_, err = upd.TryExecute(vc, map[string]*querypb.BindVariable{}, false)
+	require.NoError(t, err)
+	vc.ExpectLog(t, []string{
+		`ResolveDestinationsMultiCol ks [[INT64(1)]] Destinations:DestinationKeyRange(01-02)`,
+		`ExecuteMultiShard ks.-20: dummy_update {} true true`,
+	})
+}
+
 func buildTestVSchema() *vindexes.VSchema {
 	invschema := &vschemapb.SrvVSchema{
 		Keyspaces: map[string]*vschemapb.Keyspace{
diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.txt b/go/vt/vtgate/planbuilder/testdata/dml_cases.txt
index c451a31a15..8bac0581f0 100644
--- a/go/vt/vtgate/planbuilder/testdata/dml_cases.txt
+++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.txt
@@ -2761,7 +2761,7 @@ Gen4 plan same as above
     "KsidLength": 2,
     "KsidVindex": "multicolIdx",
     "MultiShardAutocommit": false,
-    "OwnedVindexQuery": "select cola, colb, colc from multicol_tbl where cola = 1 and colb = 2 for update",
+    "OwnedVindexQuery": "select cola, colb, colc, `name` from multicol_tbl where cola = 1 and colb = 2 for update",
     "Query": "delete from multicol_tbl where cola = 1 and colb = 2",
     "Table": "multicol_tbl",
     "Values": [
@@ -2789,7 +2789,7 @@ Gen4 plan same as above
     "KsidLength": 2,
     "KsidVindex": "multicolIdx",
     "MultiShardAutocommit": false,
-    "OwnedVindexQuery": "select cola, colb, colc from multicol_tbl where colb = 2 and cola = 1 for update",
+    "OwnedVindexQuery": "select cola, colb, colc, `name` from multicol_tbl where colb = 2 and cola = 1 for update",
     "Query": "delete from multicol_tbl where colb = 2 and cola = 1",
     "Table": "multicol_tbl",
     "Values": [
@@ -2817,7 +2817,7 @@ Gen4 plan same as above
     "KsidLength": 2,
     "KsidVindex": "multicolIdx",
     "MultiShardAutocommit": false,
-    "OwnedVindexQuery": "select cola, colb, colc from multicol_tbl where colb in (1, 2) and cola = 1 for update",
+    "OwnedVindexQuery": "select cola, colb, colc, `name` from multicol_tbl where colb in (1, 2) and cola = 1 for update",
     "Query": "delete from multicol_tbl where colb in (1, 2) and cola = 1",
     "Table": "multicol_tbl",
     "Values": [
@@ -2845,7 +2845,7 @@ Gen4 plan same as above
     "KsidLength": 2,
     "KsidVindex": "multicolIdx",
     "MultiShardAutocommit": false,
-    "OwnedVindexQuery": "select cola, colb, colc from multicol_tbl where colb in (1, 2) and cola in (3, 4) for update",
+    "OwnedVindexQuery": "select cola, colb, colc, `name` from multicol_tbl where colb in (1, 2) and cola in (3, 4) for update",
     "Query": "delete from multicol_tbl where colb in (1, 2) and cola in (3, 4)",
     "Table": "multicol_tbl",
     "Values": [
@@ -2871,12 +2871,12 @@ Gen4 plan same as above
     },
     "TargetTabletType": "PRIMARY",
     "ChangedVindexValues": [
-      "colc_map:3"
+      "colc_map:4"
     ],
     "KsidLength": 2,
     "KsidVindex": "multicolIdx",
     "MultiShardAutocommit": false,
-    "OwnedVindexQuery": "select cola, colb, colc, colc = 1 from multicol_tbl where cola = 1 and colb = 2 for update",
+    "OwnedVindexQuery": "select cola, colb, colc, `name`, colc = 1 from multicol_tbl where cola = 1 and colb = 2 for update",
     "Query": "update multicol_tbl set colc = 1 where cola = 1 and colb = 2",
     "Table": "multicol_tbl",
     "Values": [
@@ -2887,3 +2887,243 @@ Gen4 plan same as above
   }
 }
 Gen4 plan same as above
+
+# update with routing using non-unique lookup vindex
+"update multicol_tbl set x = 42 where name = 'foo'"
+{
+  "QueryType": "UPDATE",
+  "Original": "update multicol_tbl set x = 42 where name = 'foo'",
+  "Instructions": {
+    "OperatorType": "Update",
+    "Variant": "Equal",
+    "Keyspace": {
+      "Name": "user",
+      "Sharded": true
+    },
+    "TargetTabletType": "PRIMARY",
+    "MultiShardAutocommit": false,
+    "Query": "update multicol_tbl set x = 42 where `name` = 'foo'",
+    "Table": "multicol_tbl",
+    "Values": [
+      "VARBINARY(\"foo\")"
+    ],
+    "Vindex": "name_muticoltbl_map"
+  }
+}
+Gen4 plan same as above
+
+# update with routing using subsharding column
+"update multicol_tbl set x = 42 where cola = 1"
+{
+  "QueryType": "UPDATE",
+  "Original": "update multicol_tbl set x = 42 where cola = 1",
+  "Instructions": {
+    "OperatorType": "Update",
+    "Variant": "Equal",
+    "Keyspace": {
+      "Name": "user",
+      "Sharded": true
+    },
+    "TargetTabletType": "PRIMARY",
+    "MultiShardAutocommit": false,
+    "Query": "update multicol_tbl set x = 42 where cola = 1",
+    "Table": "multicol_tbl",
+    "Values": [
+      "INT64(1)"
+    ],
+    "Vindex": "multicolIdx"
+  }
+}
+Gen4 plan same as above
+
+# update with routing using subsharding column on lookup vindex
+"update multicol_tbl set name = 'bar' where cola = 1"
+{
+  "QueryType": "UPDATE",
+  "Original": "update multicol_tbl set name = 'bar' where cola = 1",
+  "Instructions": {
+    "OperatorType": "Update",
+    "Variant": "Equal",
+    "Keyspace": {
+      "Name": "user",
+      "Sharded": true
+    },
+    "TargetTabletType": "PRIMARY",
+    "ChangedVindexValues": [
+      "name_muticoltbl_map:4"
+    ],
+    "KsidLength": 2,
+    "KsidVindex": "multicolIdx",
+    "MultiShardAutocommit": false,
+    "OwnedVindexQuery": "select cola, colb, colc, `name`, `name` = 'bar' from multicol_tbl where cola = 1 for update",
+    "Query": "update multicol_tbl set `name` = 'bar' where cola = 1",
+    "Table": "multicol_tbl",
+    "Values": [
+      "INT64(1)"
+    ],
+    "Vindex": "multicolIdx"
+  }
+}
+Gen4 plan same as above
+
+# update with routing using subsharding column with in query
+"update multicol_tbl set name = 'bar' where cola in (1,2)"
+{
+  "QueryType": "UPDATE",
+  "Original": "update multicol_tbl set name = 'bar' where cola in (1,2)",
+  "Instructions": {
+    "OperatorType": "Update",
+    "Variant": "IN",
+    "Keyspace": {
+      "Name": "user",
+      "Sharded": true
+    },
+    "TargetTabletType": "PRIMARY",
+    "ChangedVindexValues": [
+      "name_muticoltbl_map:4"
+    ],
+    "KsidLength": 2,
+    "KsidVindex": "multicolIdx",
+    "MultiShardAutocommit": false,
+    "OwnedVindexQuery": "select cola, colb, colc, `name`, `name` = 'bar' from multicol_tbl where cola in (1, 2) for update",
+    "Query": "update multicol_tbl set `name` = 'bar' where cola in (1, 2)",
+    "Table": "multicol_tbl",
+    "Values": [
+      "(INT64(1), INT64(2))"
+    ],
+    "Vindex": "multicolIdx"
+  }
+}
+Gen4 plan same as above
+
+# update with routing using subsharding column with in query as lower cost over lookup vindex
+"update multicol_tbl set x = 1 where name = 'foo' and cola = 2"
+{
+  "QueryType": "UPDATE",
+  "Original": "update multicol_tbl set x = 1 where name = 'foo' and cola = 2",
+  "Instructions": {
+    "OperatorType": "Update",
+    "Variant": "Equal",
+    "Keyspace": {
+      "Name": "user",
+      "Sharded": true
+    },
+    "TargetTabletType": "PRIMARY",
+    "MultiShardAutocommit": false,
+    "Query": "update multicol_tbl set x = 1 where `name` = 'foo' and cola = 2",
+    "Table": "multicol_tbl",
+    "Values": [
+      "INT64(2)"
+    ],
+    "Vindex": "multicolIdx"
+  }
+}
+Gen4 plan same as above
+
+# delete with routing using non-unique lookup vindex
+"delete from multicol_tbl where name = 'foo'"
+{
+  "QueryType": "DELETE",
+  "Original": "delete from multicol_tbl where name = 'foo'",
+  "Instructions": {
+    "OperatorType": "Delete",
+    "Variant": "Equal",
+    "Keyspace": {
+      "Name": "user",
+      "Sharded": true
+    },
+    "TargetTabletType": "PRIMARY",
+    "KsidLength": 2,
+    "KsidVindex": "multicolIdx",
+    "MultiShardAutocommit": false,
+    "OwnedVindexQuery": "select cola, colb, colc, `name` from multicol_tbl where `name` = 'foo' for update",
+    "Query": "delete from multicol_tbl where `name` = 'foo'",
+    "Table": "multicol_tbl",
+    "Values": [
+      "VARBINARY(\"foo\")"
+    ],
+    "Vindex": "name_muticoltbl_map"
+  }
+}
+Gen4 plan same as above
+
+# delete with routing using subsharding column
+"delete from multicol_tbl where cola = 1"
+{
+  "QueryType": "DELETE",
+  "Original": "delete from multicol_tbl where cola = 1",
+  "Instructions": {
+    "OperatorType": "Delete",
+    "Variant": "Equal",
+    "Keyspace": {
+      "Name": "user",
+      "Sharded": true
+    },
+    "TargetTabletType": "PRIMARY",
+    "KsidLength": 2,
+    "KsidVindex": "multicolIdx",
+    "MultiShardAutocommit": false,
+    "OwnedVindexQuery": "select cola, colb, colc, `name` from multicol_tbl where cola = 1 for update",
+    "Query": "delete from multicol_tbl where cola = 1",
+    "Table": "multicol_tbl",
+    "Values": [
+      "INT64(1)"
+    ],
+    "Vindex": "multicolIdx"
+  }
+}
+Gen4 plan same as above
+
+# delete with routing using subsharding column with in query
+"delete from multicol_tbl where cola in (1,2)"
+{
+  "QueryType": "DELETE",
+  "Original": "delete from multicol_tbl where cola in (1,2)",
+  "Instructions": {
+    "OperatorType": "Delete",
+    "Variant": "IN",
+    "Keyspace": {
+      "Name": "user",
+      "Sharded": true
+    },
+    "TargetTabletType": "PRIMARY",
+    "KsidLength": 2,
+    "KsidVindex": "multicolIdx",
+    "MultiShardAutocommit": false,
+    "OwnedVindexQuery": "select cola, colb, colc, `name` from multicol_tbl where cola in (1, 2) for update",
+    "Query": "delete from multicol_tbl where cola in (1, 2)",
+    "Table": "multicol_tbl",
+    "Values": [
+      "(INT64(1), INT64(2))"
+    ],
+    "Vindex": "multicolIdx"
+  }
+}
+Gen4 plan same as above
+
+# delete with routing using subsharding column with in query as lower cost over lookup vindex
+"delete from multicol_tbl where name = 'foo' and cola = 2"
+{
+  "QueryType": "DELETE",
+  "Original": "delete from multicol_tbl where name = 'foo' and cola = 2",
+  "Instructions": {
+    "OperatorType": "Delete",
+    "Variant": "Equal",
+    "Keyspace": {
+      "Name": "user",
+      "Sharded": true
+    },
+    "TargetTabletType": "PRIMARY",
+    "KsidLength": 2,
+    "KsidVindex": "multicolIdx",
+    "MultiShardAutocommit": false,
+    "OwnedVindexQuery": "select cola, colb, colc, `name` from multicol_tbl where `name` = 'foo' and cola = 2 for update",
+    "Query": "delete from multicol_tbl where `name` = 'foo' and cola = 2",
+    "Table": "multicol_tbl",
+    "Values": [
+      "INT64(2)"
+    ],
+    "Vindex": "multicolIdx"
+  }
+}
+Gen4 plan same as above
diff --git a/go/vt/vtgate/planbuilder/testdata/schema_test.json b/go/vt/vtgate/planbuilder/testdata/schema_test.json
index 827452ae25..26992b77fb 100644
--- a/go/vt/vtgate/planbuilder/testdata/schema_test.json
+++ b/go/vt/vtgate/planbuilder/testdata/schema_test.json
@@ -91,6 +91,10 @@
         "colc_map": {
           "type": "lookup_test",
           "owner": "multicol_tbl"
+        },
+        "name_muticoltbl_map": {
+          "type": "name_lkp_test",
+          "owner": "multicol_tbl"
         }
       },
       "tables": {
@@ -308,6 +312,10 @@
             {
               "column": "colc",
               "name": "colc_map"
+            },
+            {
+              "column": "name",
+              "name": "name_muticoltbl_map"
             }
           ]
         }
diff --git a/go/vt/wrangler/traffic_switcher_test.go b/go/vt/wrangler/traffic_switcher_test.go
index c788baf462..a91b48f725 100644
--- a/go/vt/wrangler/traffic_switcher_test.go
+++ b/go/vt/wrangler/traffic_switcher_test.go
@@ -822,17 +822,17 @@ func testTableMigrateOneToMany(t *testing.T, keepData, keepRoutingRules bool) {
 	}
 	waitForCatchup()
 
-	deleteReverseReplication := func() {
+	deleteReverseReplicaion := func() {
 		tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1' and workflow = 'test_reverse'", resultid34, nil)
 		tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil)
 		tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil)
 	}
 
 	createReverseVReplication := func() {
-		deleteReverseReplication()
+		deleteReverseReplicaion()
 
-		tme.dbSourceClients[0].addQueryRE(`insert into _vt.vreplication.*test_reverse.*ks2.*-80.*t1.*from `+"`"+"t1`"+`\\".*t2.*from `+"`"+"t2`"+`\\"`, &sqltypes.Result{InsertID: 1}, nil)
-		tme.dbSourceClients[0].addQueryRE(`insert into _vt.vreplication.*test_reverse.*ks2.*80-.*t1.*from `+"`"+"t1`"+`\\".*t2.*from `+"`"+"t2`"+`\\"`, &sqltypes.Result{InsertID: 2}, nil)
+		tme.dbSourceClients[0].addQueryRE(`insert into _vt.vreplication.*test_reverse.*ks2.*-80.*t1.*from t1\\".*t2.*from t2\\"`, &sqltypes.Result{InsertID: 1}, nil)
+		tme.dbSourceClients[0].addQueryRE(`insert into _vt.vreplication.*test_reverse.*ks2.*80-.*t1.*from t1\\".*t2.*from t2\\"`, &sqltypes.Result{InsertID: 2}, nil)
 		tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil)
 		tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil)
 	}
diff --git a/go/vt/wrangler/workflow_test.go b/go/vt/wrangler/workflow_test.go
index 3629f3c5b1..365bb87421 100644
--- a/go/vt/wrangler/workflow_test.go
+++ b/go/vt/wrangler/workflow_test.go
@@ -563,10 +563,10 @@ func expectMoveTablesQueries(t *testing.T, tme *testMigraterEnv) {
 	tme.dbSourceClients[0].addInvariant("select pos, state, message from _vt.vreplication where id=2", state)
 	tme.dbSourceClients[1].addInvariant("select pos, state, message from _vt.vreplication where id=1", state)
 	tme.dbSourceClients[1].addInvariant("select pos, state, message from _vt.vreplication where id=2", state)
-	tme.tmeDB.AddQuery("drop table `vt_ks1`.`t1`", noResult)
-	tme.tmeDB.AddQuery("drop table `vt_ks1`.`t2`", noResult)
-	tme.tmeDB.AddQuery("drop table `vt_ks2`.`t1`", noResult)
-	tme.tmeDB.AddQuery("drop table `vt_ks2`.`t2`", noResult)
+	tme.tmeDB.AddQuery("drop table vt_ks1.t1", noResult)
+	tme.tmeDB.AddQuery("drop table vt_ks1.t2", noResult)
+	tme.tmeDB.AddQuery("drop table vt_ks2.t1", noResult)
+	tme.tmeDB.AddQuery("drop table vt_ks2.t2", noResult)
 	tme.tmeDB.AddQuery("update _vt.vreplication set message='Picked source tablet: cell:\"cell1\" uid:10 ' where id=1", noResult)
 	tme.tmeDB.AddQuery("lock tables `t1` read,`t2` read", &sqltypes.Result{})
 	tme.tmeDB.AddQuery("select 1 from _vt.copy_state cs, _vt.vreplication vr where vr.id = cs.vrepl_id and vr.id = 1", noResult)
diff --git a/test/config.json b/test/config.json
index 24bcf08c18..7a5607d764 100644
--- a/test/config.json
+++ b/test/config.json
@@ -127,7 +127,7 @@
 			"Manual": false,
 			"Shard": "19",
 			"RetryMax": 1,
-			"Tags": ["upgrade_downgrade_backups"]
+			"Tags": []
 		},
 		"backup_transform": {
 			"File": "unused.go",
@@ -136,7 +136,7 @@
 			"Manual": false,
 			"Shard": "19",
 			"RetryMax": 1,
-			"Tags": ["upgrade_downgrade_backups"]
+			"Tags": []
 		},
 		"backup_transform_mysqlctld": {
 			"File": "unused.go",