Repository: vitessio/vitess
Pull request #6666 (2020-09-03 05:55:22)

only take on simple dual queries in the vtgate


Patch:
diff --git a/Makefile b/Makefile
index a4562845ec..9872d582dd 100644
--- a/Makefile
+++ b/Makefile
@@ -37,12 +37,6 @@ ifdef VT_EXTRA_BUILD_FLAGS
 export EXTRA_BUILD_FLAGS := $(VT_EXTRA_BUILD_FLAGS)
 endif
 
-# We now have CGO code in the build which throws warnings with newer gcc builds.
-# See: https://github.com/mattn/go-sqlite3/issues/803
-# Work around by dropping optimization level from default -O2.
-# Safe, since this code isn't performance critical.
-export CGO_CFLAGS := -O1
-
 embed_config:
 	cd go/vt/mysqlctl
 	go run github.com/GeertJohan/go.rice/rice embed-go
diff --git a/config/orchestrator/default.json b/config/orchestrator/default.json
deleted file mode 100644
index c68029c540..0000000000
--- a/config/orchestrator/default.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "Debug": true,
-  "MySQLTopologyUser": "orc_client_user",
-  "MySQLTopologyPassword": "orc_client_user_password",
-  "MySQLReplicaUser": "vt_repl",
-  "MySQLReplicaPassword": "",
-  "BackendDB": "sqlite",
-  "SQLite3DataFile": "/home/sougou/dev/src/vitess.io/vitess/vtdataroot/orchestrator.sqlite3",
-  "RecoverMasterClusterFilters": ["*"],
-  "RecoveryPeriodBlockSeconds": 1,
-  "DelayMasterPromotionIfSQLThreadNotUpToDate": true
-}
diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common
index 92ca899f71..4ee1e190b9 100644
--- a/docker/bootstrap/Dockerfile.common
+++ b/docker/bootstrap/Dockerfile.common
@@ -6,7 +6,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins
     automake \
     bison \
     bzip2 \
-    chromium \
+    chromium=70.0.3538.110-1~deb9u1 \
     curl \
     g++ \
     git \
diff --git a/go/cmd/orchestrator/main.go b/go/cmd/orchestrator/main.go
index cd7e70c583..85b828f7ce 100644
--- a/go/cmd/orchestrator/main.go
+++ b/go/cmd/orchestrator/main.go
@@ -31,7 +31,6 @@ var AppVersion, GitCommit string
 
 // main is the application's entry point. It will either spawn a CLI or HTTP itnerfaces.
 func main() {
-	// TODO(sougou): change this to use vitess servenv framework
 	configFile := flag.String("config", "", "config file name")
 	command := flag.String("c", "", "command, required. See full list of commands via 'orchestrator -c help'")
 	strict := flag.Bool("strict", false, "strict mode (more checks, slower)")
@@ -58,6 +57,7 @@ func main() {
 	config.RuntimeCLIFlags.Statement = flag.String("statement", "", "Statement/hint")
 	config.RuntimeCLIFlags.GrabElection = flag.Bool("grab-election", false, "Grab leadership (only applies to continuous mode)")
 	config.RuntimeCLIFlags.PromotionRule = flag.String("promotion-rule", "prefer", "Promotion rule for register-andidate (prefer|neutral|prefer_not|must_not)")
+	config.RuntimeCLIFlags.Version = flag.Bool("version", false, "Print version and exit")
 	config.RuntimeCLIFlags.SkipContinuousRegistration = flag.Bool("skip-continuous-registration", false, "Skip cli commands performaing continuous registration (to reduce orchestratrator backend db load")
 	config.RuntimeCLIFlags.EnableDatabaseUpdate = flag.Bool("enable-database-update", false, "Enable database update, overrides SkipOrchestratorDatabaseUpdate")
 	config.RuntimeCLIFlags.IgnoreRaftSetup = flag.Bool("ignore-raft-setup", false, "Override RaftEnabled for CLI invocation (CLI by default not allowed for raft setups). NOTE: operations by CLI invocation may not reflect in all raft nodes.")
@@ -91,6 +91,11 @@ func main() {
 	if *stack {
 		log.SetPrintStackTrace(*stack)
 	}
+	if *config.RuntimeCLIFlags.Version {
+		fmt.Println(AppVersion)
+		fmt.Println(GitCommit)
+		return
+	}
 
 	startText := "starting orchestrator"
 	if AppVersion != "" {
diff --git a/go/cmd/orchestrator/plugin_consultopo.go b/go/cmd/orchestrator/plugin_consultopo.go
deleted file mode 100644
index 59d6774fdb..0000000000
--- a/go/cmd/orchestrator/plugin_consultopo.go
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-Copyright 2019 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 agreedto 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.
-*/
-
-package main
-
-// This plugin imports consultopo to register the consul implementation of TopoServer.
-
-import (
-	_ "vitess.io/vitess/go/vt/topo/consultopo"
-)
diff --git a/go/cmd/orchestrator/plugin_etcd2topo.go b/go/cmd/orchestrator/plugin_etcd2topo.go
deleted file mode 100644
index d99ef51d4a..0000000000
--- a/go/cmd/orchestrator/plugin_etcd2topo.go
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-Copyright 2019 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.
-*/
-
-package main
-
-// This plugin imports etcd2topo to register the etcd2 implementation of TopoServer.
-
-import (
-	_ "vitess.io/vitess/go/vt/topo/etcd2topo"
-)
diff --git a/go/cmd/orchestrator/plugin_grpctmclient.go b/go/cmd/orchestrator/plugin_grpctmclient.go
deleted file mode 100644
index ce554da96d..0000000000
--- a/go/cmd/orchestrator/plugin_grpctmclient.go
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-Copyright 2019 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.
-*/
-
-package main
-
-// Imports and register the gRPC tabletmanager client
-
-import (
-	_ "vitess.io/vitess/go/vt/vttablet/grpctmclient"
-)
diff --git a/go/cmd/orchestrator/plugin_zk2topo.go b/go/cmd/orchestrator/plugin_zk2topo.go
deleted file mode 100644
index ebf385ec1a..0000000000
--- a/go/cmd/orchestrator/plugin_zk2topo.go
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-Copyright 2019 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 agreedto 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.
-*/
-
-package main
-
-// Imports and register the zk2 TopologyServer
-
-import (
-	_ "vitess.io/vitess/go/vt/topo/zk2topo"
-)
diff --git a/go/vt/orchestrator/app/http.go b/go/vt/orchestrator/app/http.go
index 96cdf60605..8a81794807 100644
--- a/go/vt/orchestrator/app/http.go
+++ b/go/vt/orchestrator/app/http.go
@@ -109,11 +109,11 @@ func standardHttp(continuousDiscovery bool) {
 	m.Use(gzip.All())
 	// Render html templates from templates directory
 	m.Use(render.Renderer(render.Options{
-		Directory:       "web/orchestrator",
+		Directory:       "resources",
 		Layout:          "templates/layout",
 		HTMLContentType: "text/html",
 	}))
-	m.Use(martini.Static("web/orchestrator/public", martini.StaticOptions{Prefix: config.Config.URLPrefix}))
+	m.Use(martini.Static("resources/public", martini.StaticOptions{Prefix: config.Config.URLPrefix}))
 	if config.Config.UseMutualTLS {
 		m.Use(ssl.VerifyOUs(config.Config.SSLValidOUs))
 	}
diff --git a/go/vt/orchestrator/config/config.go b/go/vt/orchestrator/config/config.go
index ecf2838bf0..81c14aea86 100644
--- a/go/vt/orchestrator/config/config.go
+++ b/go/vt/orchestrator/config/config.go
@@ -65,7 +65,6 @@ const (
 // Configuration makes for orchestrator configuration input, which can be provided by user via JSON formatted file.
 // Some of the parameteres have reasonable default values, and some (like database credentials) are
 // strictly expected from user.
-// TODO(sougou): change this to yaml parsing, and possible merge with tabletenv.
 type Configuration struct {
 	Debug                                      bool   // set debug mode (similar to --debug option)
 	EnableSyslog                               bool   // Should logs be directed (in addition) to syslog daemon?
@@ -75,8 +74,6 @@ type Configuration struct {
 	AgentsServerPort                           string // port orchestrator agents talk back to
 	MySQLTopologyUser                          string
 	MySQLTopologyPassword                      string
-	MySQLReplicaUser                           string // If set, use this credential instead of discovering from mysql. TODO(sougou): deprecate this in favor of fetching from vttablet
-	MySQLReplicaPassword                       string
 	MySQLTopologyCredentialsConfigFile         string // my.cnf style configuration file from where to pick credentials. Expecting `user`, `password` under `[client]` section
 	MySQLTopologySSLPrivateKeyFile             string // Private key file used to authenticate with a Topology mysql instance with TLS
 	MySQLTopologySSLCertFile                   string // Certificate PEM file used to authenticate with a Topology mysql instance with TLS
diff --git a/go/vt/orchestrator/db/generate_base.go b/go/vt/orchestrator/db/generate_base.go
index a2cdb3fad5..ee99371f71 100644
--- a/go/vt/orchestrator/db/generate_base.go
+++ b/go/vt/orchestrator/db/generate_base.go
@@ -851,18 +851,4 @@ var generateSQLBase = []string{
 	`
 		CREATE INDEX first_seen_idx_database_instance_stale_binlog_coordinates ON database_instance_stale_binlog_coordinates (first_seen)
 	`,
-	`
-		CREATE TABLE IF NOT EXISTS vitess_tablet (
-			hostname varchar(128) CHARACTER SET ascii NOT NULL,
-			port smallint(5) unsigned NOT NULL,
-			cell varchar(128) CHARACTER SET ascii NOT NULL,
-			tablet_type smallint(5) NOT NULL,
-			master_timestamp timestamp NOT NULL,
-			info varchar(512) CHARACTER SET ascii NOT NULL,
-			PRIMARY KEY (hostname, port)
-		) ENGINE=InnoDB DEFAULT CHARSET=ascii
-	`,
-	`
-		CREATE INDEX cell_idx_vitess_tablet ON vitess_tablet (cell)
-	`,
 }
diff --git a/go/vt/orchestrator/external/golib/log/log.go b/go/vt/orchestrator/external/golib/log/log.go
index 92f8256e43..26d33c9973 100644
--- a/go/vt/orchestrator/external/golib/log/log.go
+++ b/go/vt/orchestrator/external/golib/log/log.go
@@ -21,12 +21,8 @@ import (
 	"fmt"
 	"log/syslog"
 	"os"
-	"runtime"
 	"runtime/debug"
-	"strings"
 	"time"
-
-	"vitess.io/vitess/go/vt/log"
 )
 
 // LogLevel indicates the severity of a log entry
@@ -127,11 +123,6 @@ func SetSyslogLevel(logLevel LogLevel) {
 
 // logFormattedEntry nicely formats and emits a log entry
 func logFormattedEntry(logLevel LogLevel, message string, args ...interface{}) string {
-	return logDepth(logLevel, 0, message, args...)
-}
-
-// logFormattedEntry nicely formats and emits a log entry
-func logDepth(logLevel LogLevel, depth int, message string, args ...interface{}) string {
 	if logLevel > globalLogLevel {
 		return ""
 	}
@@ -146,8 +137,7 @@ func logDepth(logLevel LogLevel, depth int, message string, args ...interface{})
 	}
 
 	msgArgs := fmt.Sprintf(message, args...)
-	sourceFile, pos := callerPos(depth)
-	entryString := fmt.Sprintf("%s %8s %s:%d] %s", localizedTime.Format(TimeFormat), logLevel, sourceFile, pos, msgArgs)
+	entryString := fmt.Sprintf("%s %s %s", localizedTime.Format(TimeFormat), logLevel, msgArgs)
 	fmt.Fprintln(os.Stderr, entryString)
 
 	if syslogWriter != nil {
@@ -177,27 +167,13 @@ func logDepth(logLevel LogLevel, depth int, message string, args ...interface{})
 	return entryString
 }
 
-func callerPos(depth int) (string, int) {
-	_, file, line, ok := runtime.Caller(4 + depth)
-	if !ok {
-		file = "???"
-		line = 1
-	} else {
-		slash := strings.LastIndex(file, "/")
-		if slash >= 0 {
-			file = file[slash+1:]
-		}
-	}
-	return file, line
-}
-
 // logEntry emits a formatted log entry
 func logEntry(logLevel LogLevel, message string, args ...interface{}) string {
 	entryString := message
 	for _, s := range args {
 		entryString += fmt.Sprintf(" %s", s)
 	}
-	return logDepth(logLevel, 1, entryString)
+	return logFormattedEntry(logLevel, entryString)
 }
 
 // logErrorEntry emits a log entry based on given error object
@@ -223,8 +199,7 @@ func Debugf(message string, args ...interface{}) string {
 }
 
 func Info(message string, args ...interface{}) string {
-	log.Infof(message, args...)
-	return fmt.Sprintf(message, args...)
+	return logEntry(INFO, message, args...)
 }
 
 func Infof(message string, args ...interface{}) string {
@@ -252,8 +227,7 @@ func Error(message string, args ...interface{}) error {
 }
 
 func Errorf(message string, args ...interface{}) error {
-	log.Infof(message, args...)
-	return fmt.Errorf(message, args...)
+	return errors.New(logFormattedEntry(ERROR, message, args...))
 }
 
 func Errore(err error) error {
diff --git a/go/vt/orchestrator/inst/analysis.go b/go/vt/orchestrator/inst/analysis.go
index e052466007..3b1ea3d5b7 100644
--- a/go/vt/orchestrator/inst/analysis.go
+++ b/go/vt/orchestrator/inst/analysis.go
@@ -20,10 +20,8 @@ import (
 	"encoding/json"
 	"fmt"
 	"strings"
-	"time"
 
 	"vitess.io/vitess/go/vt/orchestrator/config"
-	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
 )
 
 type AnalysisCode string
@@ -31,17 +29,10 @@ type StructureAnalysisCode string
 
 const (
 	NoProblem                                               AnalysisCode = "NoProblem"
-	ClusterHasNoMaster                                      AnalysisCode = "ClusterHasNoMaster"
 	DeadMasterWithoutReplicas                               AnalysisCode = "DeadMasterWithoutReplicas"
 	DeadMaster                                              AnalysisCode = "DeadMaster"
 	DeadMasterAndReplicas                                   AnalysisCode = "DeadMasterAndReplicas"
 	DeadMasterAndSomeReplicas                               AnalysisCode = "DeadMasterAndSomeReplicas"
-	MasterHasMaster                                         AnalysisCode = "MasterHasMaster"
-	MasterIsReadOnly                                        AnalysisCode = "MasterIsReadOnly"
-	ReplicaIsWritable                                       AnalysisCode = "ReplicaIsWritable"
-	NotConnectedToMaster                                    AnalysisCode = "NotConnectedToMaster"
-	ConnectedToWrongMaster                                  AnalysisCode = "ConnectedToWrongMaster"
-	ReplicationStopped                                      AnalysisCode = "ReplicationStopped"
 	UnreachableMasterWithLaggingReplicas                    AnalysisCode = "UnreachableMasterWithLaggingReplicas"
 	UnreachableMaster                                       AnalysisCode = "UnreachableMaster"
 	MasterSingleReplicaNotReplicating                       AnalysisCode = "MasterSingleReplicaNotReplicating"
@@ -125,16 +116,12 @@ const (
 type ReplicationAnalysis struct {
 	AnalyzedInstanceKey                       InstanceKey
 	AnalyzedInstanceMasterKey                 InstanceKey
-	TabletType                                topodatapb.TabletType
-	MasterTimeStamp                           time.Time
-	SuggestedClusterAlias                     string
 	ClusterDetails                            ClusterInfo
 	AnalyzedInstanceDataCenter                string
 	AnalyzedInstanceRegion                    string
 	AnalyzedInstancePhysicalEnvironment       string
 	AnalyzedInstanceBinlogCoordinates         BinlogCoordinates
 	IsMaster                                  bool
-	IsClusterMaster                           bool
 	IsCoMaster                                bool
 	LastCheckValid                            bool
 	LastCheckPartialSuccess                   bool
@@ -147,7 +134,6 @@ type ReplicationAnalysis struct {
 	Replicas                                  InstanceKeyMap
 	SlaveHosts                                InstanceKeyMap // for backwards compatibility. Equals `Replicas`
 	IsFailingToConnectToMaster                bool
-	ReplicationStopped                        bool
 	Analysis                                  AnalysisCode
 	Description                               string
 	StructureAnalysis                         []StructureAnalysisCode
diff --git a/go/vt/orchestrator/inst/analysis_dao.go b/go/vt/orchestrator/inst/analysis_dao.go
index 42e6cbf130..70e14e4b12 100644
--- a/go/vt/orchestrator/inst/analysis_dao.go
+++ b/go/vt/orchestrator/inst/analysis_dao.go
@@ -25,10 +25,7 @@ import (
 	"vitess.io/vitess/go/vt/orchestrator/db"
 	"vitess.io/vitess/go/vt/orchestrator/process"
 	"vitess.io/vitess/go/vt/orchestrator/util"
-	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
-	"vitess.io/vitess/go/vt/topo"
 
-	"github.com/golang/protobuf/proto"
 	"github.com/patrickmn/go-cache"
 	"github.com/rcrowley/go-metrics"
 	"vitess.io/vitess/go/vt/orchestrator/external/golib/log"
@@ -53,24 +50,82 @@ func initializeAnalysisDaoPostConfiguration() {
 	recentInstantAnalysis = cache.New(time.Duration(config.RecoveryPollSeconds*2)*time.Second, time.Second)
 }
 
-type clusterAnalysis struct {
-	hasClusterwideAction bool
-	masterKey            *InstanceKey
-}
-
 // GetReplicationAnalysis will check for replication problems (dead master; unreachable master; etc)
 func GetReplicationAnalysis(clusterName string, hints *ReplicationAnalysisHints) ([]ReplicationAnalysis, error) {
 	result := []ReplicationAnalysis{}
 
-	// TODO(sougou); deprecate ReduceReplicationAnalysisCount
 	args := sqlutils.Args(config.Config.ReasonableReplicationLagSeconds, ValidSecondsFromSeenToLastAttemptedCheck(), config.Config.ReasonableReplicationLagSeconds, clusterName)
-	query := `
+	analysisQueryReductionClause := ``
+
+	if config.Config.ReduceReplicationAnalysisCount {
+		analysisQueryReductionClause = `
+			HAVING
+				(
+					MIN(
+						master_instance.last_checked <= master_instance.last_seen
+						and master_instance.last_attempted_check <= master_instance.last_seen + interval ? second
+					) = 1
+					/* AS is_last_check_valid */
+				) = 0
+				OR (
+					IFNULL(
+						SUM(
+							replica_instance.last_checked <= replica_instance.last_seen
+							AND replica_instance.slave_io_running = 0
+							AND replica_instance.last_io_error like '%error %connecting to master%'
+							AND replica_instance.slave_sql_running = 1
+						),
+						0
+					)
+					/* AS count_replicas_failing_to_connect_to_master */
+					> 0
+				)
+				OR (
+					IFNULL(
+						SUM(
+							replica_instance.last_checked <= replica_instance.last_seen
+						),
+						0
+					)
+					/* AS count_valid_replicas */
+					< COUNT(replica_instance.server_id)
+					/* AS count_replicas */
+				)
+				OR (
+					IFNULL(
+						SUM(
+							replica_instance.last_checked <= replica_instance.last_seen
+							AND replica_instance.slave_io_running != 0
+							AND replica_instance.slave_sql_running != 0
+						),
+						0
+					)
+					/* AS count_valid_replicating_replicas */
+					< COUNT(replica_instance.server_id)
+					/* AS count_replicas */
+				)
+				OR (
+					MIN(
+						master_instance.slave_sql_running = 1
+						AND master_instance.slave_io_running = 0
+						AND master_instance.last_io_error like '%error %connecting to master%'
+					)
+					/* AS is_failing_to_connect_to_master */
+				)
+				OR (
+					COUNT(replica_instance.server_id)
+					/* AS count_replicas */
+					> 0
+				)
+			`
+		args = append(args, ValidSecondsFromSeenToLastAttemptedCheck())
+	}
+	// "OR count_replicas > 0" above is a recent addition, which, granted, makes some previous conditions redundant.
+	// It gives more output, and more "NoProblem" messages that I am now interested in for purpose of auditing in database_instance_analysis_changelog
+	query := fmt.Sprintf(`
 	SELECT
-		vitess_tablet.info AS tablet_info,
-		vitess_tablet.hostname,
-		vitess_tablet.port,
-		vitess_tablet.tablet_type,
-		vitess_tablet.master_timestamp,
+		master_instance.hostname,
+		master_instance.port,
 		master_instance.read_only AS read_only,
 		MIN(master_instance.data_center) AS data_center,
 		MIN(master_instance.region) AS region,
@@ -80,7 +135,6 @@ func GetReplicationAnalysis(clusterName string, hints *ReplicationAnalysisHints)
 		MIN(master_instance.cluster_name) AS cluster_name,
 		MIN(master_instance.binary_log_file) AS binary_log_file,
 		MIN(master_instance.binary_log_pos) AS binary_log_pos,
-		MIN(master_instance.suggested_cluster_alias) AS suggested_cluster_alias,
 		MIN(
 			IFNULL(
 				master_instance.binary_log_file = database_instance_stale_binlog_coordinates.binary_log_file
@@ -165,10 +219,6 @@ func GetReplicationAnalysis(clusterName string, hints *ReplicationAnalysisHints)
 			AND master_instance.slave_io_running = 0
 			AND master_instance.last_io_error like '%%error %%connecting to master%%'
 		) AS is_failing_to_connect_to_master,
-		MIN(
-			master_instance.slave_sql_running = 0
-			AND master_instance.slave_io_running = 0
-		) AS replication_stopped,
 		MIN(
 			master_downtime.downtime_active is not null
 			and ifnull(master_downtime.end_timestamp, now()) > now()
@@ -301,11 +351,7 @@ func GetReplicationAnalysis(clusterName string, hints *ReplicationAnalysisHints)
 			AND replica_instance.log_slave_updates then replica_instance.major_version else NULL end
 		) AS count_distinct_logging_major_versions
 	FROM
-		vitess_tablet
-		LEFT JOIN database_instance master_instance ON (
-			vitess_tablet.hostname = master_instance.hostname
-			AND vitess_tablet.port = master_instance.port
-		)
+		database_instance master_instance
 		LEFT JOIN hostname_resolve ON (
 			master_instance.hostname = hostname_resolve.hostname
 		)
@@ -345,14 +391,16 @@ func GetReplicationAnalysis(clusterName string, hints *ReplicationAnalysisHints)
 		database_instance_maintenance.database_instance_maintenance_id IS NULL
 		AND ? IN ('', master_instance.cluster_name)
 	GROUP BY
-		vitess_tablet.hostname,
-		vitess_tablet.port
+		master_instance.hostname,
+		master_instance.port
+		%s
 	ORDER BY
-		tablet_type ASC,
-		master_timestamp DESC
-	`
+		is_master DESC,
+		is_cluster_master DESC,
+		count_replicas DESC
+	`,
+		analysisQueryReductionClause)
 
-	clusters := make(map[string]*clusterAnalysis)
 	err := db.QueryOrchestrator(query, args, func(m sqlutils.RowMap) error {
 		a := ReplicationAnalysis{
 			Analysis:               NoProblem,
@@ -360,15 +408,6 @@ func GetReplicationAnalysis(clusterName string, hints *ReplicationAnalysisHints)
 			ProcessingNodeToken:    util.ProcessToken.Hash,
 		}
 
-		tablet := &topodatapb.Tablet{}
-		if err := proto.UnmarshalText(m.GetString("tablet_info"), tablet); err != nil {
-			log.Errorf("could not read tablet %v: %v", m.GetString("tablet_info"), err)
-			return nil
-		}
-
-		a.TabletType = tablet.Type
-		a.MasterTimeStamp = m.GetTime("master_timestamp")
-
 		a.IsMaster = m.GetBool("is_master")
 		countCoMasterReplicas := m.GetUint("count_co_master_replicas")
 		a.IsCoMaster = m.GetBool("is_co_master") || (countCoMasterReplicas > 0)
@@ -383,7 +422,6 @@ func GetReplicationAnalysis(clusterName string, hints *ReplicationAnalysisHints)
 			Type:    BinaryLog,
 		}
 		isStaleBinlogCoordinates := m.GetBool("is_stale_binlog_coordinates")
-		a.SuggestedClusterAlias = m.GetString("suggested_cluster_alias")
 		a.ClusterDetails.ClusterName = m.GetString("cluster_name")
 		a.ClusterDetails.ClusterAlias = m.GetString("cluster_alias")
 		a.ClusterDetails.ClusterDomain = m.GetString("cluster_domain")
@@ -397,7 +435,6 @@ func GetReplicationAnalysis(clusterName string, hints *ReplicationAnalysisHints)
 		a.CountDowntimedReplicas = m.GetUint("count_downtimed_replicas")
 		a.ReplicationDepth = m.GetUint("replication_depth")
 		a.IsFailingToConnectToMaster = m.GetBool("is_failing_to_connect_to_master")
-		a.ReplicationStopped = m.GetBool("replication_stopped")
 		a.IsDowntimed = m.GetBool("is_downtimed")
 		a.DowntimeEndTimestamp = m.GetString("downtime_end_timestamp")
 		a.DowntimeRemainingSeconds = m.GetInt("downtime_remaining_seconds")
@@ -444,69 +481,22 @@ func GetReplicationAnalysis(clusterName string, hints *ReplicationAnalysisHints)
 				log.Debugf(analysisMessage)
 			}
 		}
-		if clusters[a.SuggestedClusterAlias] == nil {
-			clusters[a.SuggestedClusterAlias] = &clusterAnalysis{}
-			if a.TabletType == topodatapb.TabletType_MASTER {
-				a.IsClusterMaster = true
-				clusters[a.SuggestedClusterAlias].masterKey = &a.AnalyzedInstanceKey
-			}
-		}
-		// ca has clusterwide info
-		ca := clusters[a.SuggestedClusterAlias]
-		if ca.hasClusterwideAction {
-			// We can only take one cluster level action at a time.
-			return nil
-		}
-		if a.IsClusterMaster && !a.LastCheckValid && a.CountReplicas == 0 {
+		if a.IsMaster && !a.LastCheckValid && a.CountReplicas == 0 {
 			a.Analysis = DeadMasterWithoutReplicas
 			a.Description = "Master cannot be reached by orchestrator and has no replica"
-			ca.hasClusterwideAction = true
 			//
-		} else if a.IsClusterMaster && !a.LastCheckValid && a.CountValidReplicas == a.CountReplicas && a.CountValidReplicatingReplicas == 0 {
+		} else if a.IsMaster && !a.LastCheckValid && a.CountValidReplicas == a.CountReplicas && a.CountValidReplicatingReplicas == 0 {
 			a.Analysis = DeadMaster
 			a.Description = "Master cannot be reached by orchestrator and none of its replicas is replicating"
-			ca.hasClusterwideAction = true
 			//
-		} else if a.IsClusterMaster && !a.LastCheckValid && a.CountReplicas > 0 && a.CountValidReplicas == 0 && a.CountValidReplicatingReplicas == 0 {
+		} else if a.IsMaster && !a.LastCheckValid && a.CountReplicas > 0 && a.CountValidReplicas == 0 && a.CountValidReplicatingReplicas == 0 {
 			a.Analysis = DeadMasterAndReplicas
 			a.Description = "Master cannot be reached by orchestrator and none of its replicas is replicating"
-			ca.hasClusterwideAction = true
 			//
-		} else if a.IsClusterMaster && !a.LastCheckValid && a.CountValidReplicas < a.CountReplicas && a.CountValidReplicas > 0 && a.CountValidReplicatingReplicas == 0 {
+		} else if a.IsMaster && !a.LastCheckValid && a.CountValidReplicas < a.CountReplicas && a.CountValidReplicas > 0 && a.CountValidReplicatingReplicas == 0 {
 			a.Analysis = DeadMasterAndSomeReplicas
 			a.Description = "Master cannot be reached by orchestrator; some of its replicas are unreachable and none of its reachable replicas is replicating"
-			ca.hasClusterwideAction = true
-			//
-		} else if a.IsClusterMaster && !a.IsMaster {
-			a.Analysis = MasterHasMaster
-			a.Description = "Master is replicating from somewhere else"
-			ca.hasClusterwideAction = true
 			//
-		} else if a.IsClusterMaster && a.IsReadOnly {
-			a.Analysis = MasterIsReadOnly
-			a.Description = "Master is read-only"
-			//
-		} else if topo.IsReplicaType(a.TabletType) && ca.masterKey == nil {
-			a.Analysis = ClusterHasNoMaster
-			a.Description = "Cluster has no master"
-			ca.hasClusterwideAction = true
-		} else if topo.IsReplicaType(a.TabletType) && !a.IsReadOnly {
-			a.Analysis = ReplicaIsWritable
-			a.Description = "Replica is writable"
-			//
-		} else if topo.IsReplicaType(a.TabletType) && a.IsMaster {
-			a.Analysis = NotConnectedToMaster
-			a.Description = "Not connected to the master"
-			//
-		} else if topo.IsReplicaType(a.TabletType) && !a.IsMaster && ca.masterKey != nil && a.AnalyzedInstanceMasterKey != *ca.masterKey {
-			a.Analysis = ConnectedToWrongMaster
-			a.Description = "Connected to wrong master"
-			//
-		} else if topo.IsReplicaType(a.TabletType) && !a.IsMaster && a.ReplicationStopped {
-			a.Analysis = ReplicationStopped
-			a.Description = "Replication is stopped"
-			//
-			// TODO(sougou): Events below here are either ignored or not possible.
 		} else if a.IsMaster && !a.LastCheckValid && a.CountLaggingReplicas == a.CountReplicas && a.CountDelayedReplicas < a.CountReplicas && a.CountValidReplicatingReplicas > 0 {
 			a.Analysis = UnreachableMasterWithLaggingReplicas
 			a.Description = "Master cannot be reached by orchestrator and all of its replicas are lagging"
@@ -533,6 +523,7 @@ func GetReplicationAnalysis(clusterName string, hints *ReplicationAnalysisHints)
 		} else if a.IsMaster && a.LastCheckValid && a.CountReplicas == 1 && a.CountValidReplicas == a.CountReplicas && a.CountValidReplicatingReplicas == 0 {
 			a.Analysis = MasterSingleReplicaNotReplicating
 			a.Description = "Master is reachable but its single replica is not replicating"
+			//
 		} else if a.IsMaster && a.LastCheckValid && a.CountReplicas == 1 && a.CountValidReplicas == 0 {
 			a.Analysis = MasterSingleReplicaDead
 			a.Description = "Master is reachable but its single replica is dead"
diff --git a/go/vt/orchestrator/inst/candidate_database_instance_dao.go b/go/vt/orchestrator/inst/candidate_database_instance_dao.go
index acbfc701f1..d0d108bd9d 100644
--- a/go/vt/orchestrator/inst/candidate_database_instance_dao.go
+++ b/go/vt/orchestrator/inst/candidate_database_instance_dao.go
@@ -45,6 +45,7 @@ func RegisterCandidateInstance(candidate *CandidateDatabaseInstance) error {
 			`
 	writeFunc := func() error {
 		_, err := db.ExecOrchestrator(query, args...)
+		AuditOperation("register-candidate", candidate.Key(), string(candidate.PromotionRule))
 		return log.Errore(err)
 	}
 	return ExecDBWriteFunc(writeFunc)
diff --git a/go/vt/orchestrator/inst/instance_dao.go b/go/vt/orchestrator/inst/instance_dao.go
index eaae26cb86..e0fb3bdeac 100644
--- a/go/vt/orchestrator/inst/instance_dao.go
+++ b/go/vt/orchestrator/inst/instance_dao.go
@@ -34,12 +34,9 @@ import (
 	"github.com/patrickmn/go-cache"
 	"github.com/rcrowley/go-metrics"
 	"github.com/sjmudd/stopwatch"
-	"vitess.io/vitess/go/tb"
 	"vitess.io/vitess/go/vt/orchestrator/external/golib/log"
 	"vitess.io/vitess/go/vt/orchestrator/external/golib/math"
 	"vitess.io/vitess/go/vt/orchestrator/external/golib/sqlutils"
-	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
-	"vitess.io/vitess/go/vt/topo/topoproto"
 
 	"vitess.io/vitess/go/vt/orchestrator/attributes"
 	"vitess.io/vitess/go/vt/orchestrator/collection"
@@ -311,13 +308,12 @@ func expectReplicationThreadsState(instanceKey *InstanceKey, expectedState Repli
 func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool, latency *stopwatch.NamedStopwatch) (inst *Instance, err error) {
 	defer func() {
 		if r := recover(); r != nil {
-			err = logReadTopologyInstanceError(instanceKey, "Unexpected, aborting", tb.Errorf("%+v", r))
+			err = logReadTopologyInstanceError(instanceKey, "Unexpected, aborting", fmt.Errorf("%+v", r))
 		}
 	}()
 
 	var waitGroup sync.WaitGroup
 	var serverUuidWaitGroup sync.WaitGroup
-	var tablet *topodatapb.Tablet
 	readingStartTime := time.Now()
 	instance := NewInstance()
 	instanceFound := false
@@ -346,19 +342,11 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool,
 
 	latency.Start("instance")
 	db, err := db.OpenDiscovery(instanceKey.Hostname, instanceKey.Port)
+	latency.Stop("instance")
 	if err != nil {
 		goto Cleanup
 	}
 
-	tablet, err = ReadTablet(*instanceKey)
-	if err != nil {
-		goto Cleanup
-	}
-	if tablet == nil {
-		log.Errorf("tablet alias is nil")
-		goto Cleanup
-	}
-
 	instance.Key = *instanceKey
 
 	if isMaxScale, resolvedHostname, err = instance.checkMaxScale(db, latency); err != nil {
@@ -375,6 +363,7 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool,
 		}
 	}
 
+	latency.Start("instance")
 	if isMaxScale {
 		if strings.Contains(instance.Version, "1.1.0") {
 			isMaxScale110 = true
@@ -531,8 +520,6 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool,
 		goto Cleanup
 	}
 	go ResolveHostnameIPs(instance.Key.Hostname)
-
-	// TODO(sougou) delete DataCenterPattern
 	if config.Config.DataCenterPattern != "" {
 		if pattern, err := regexp.Compile(config.Config.DataCenterPattern); err == nil {
 			match := pattern.FindStringSubmatch(instance.Key.Hostname)
@@ -750,7 +737,6 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool,
 		}()
 	}
 
-	// TODO(sougou): delete DetectDataCenterQuery
 	if config.Config.DetectDataCenterQuery != "" && !isMaxScale {
 		waitGroup.Add(1)
 		go func() {
@@ -759,9 +745,7 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool,
 			logReadTopologyInstanceError(instanceKey, "DetectDataCenterQuery", err)
 		}()
 	}
-	instance.DataCenter = tablet.Alias.Cell
 
-	// TODO(sougou): use cell alias to identify regions.
 	if config.Config.DetectRegionQuery != "" && !isMaxScale {
 		waitGroup.Add(1)
 		go func() {
@@ -780,7 +764,6 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool,
 		}()
 	}
 
-	// TODO(sougou): delete DetectInstanceAliasQuery
 	if config.Config.DetectInstanceAliasQuery != "" && !isMaxScale {
 		waitGroup.Add(1)
 		go func() {
@@ -789,9 +772,7 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool,
 			logReadTopologyInstanceError(instanceKey, "DetectInstanceAliasQuery", err)
 		}()
 	}
-	instance.InstanceAlias = topoproto.TabletAliasString(tablet.Alias)
 
-	// TODO(sougou): come up with a strategy for semi-sync
 	if config.Config.DetectSemiSyncEnforcedQuery != "" && !isMaxScale {
 		waitGroup.Add(1)
 		go func() {
@@ -835,20 +816,57 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool,
 		}
 	}
 
-	// We need to update candidate_database_instance.
-	// We register the rule even if it hasn't changed,
-	// to bump the last_suggested time.
-	if tablet.Type == topodatapb.TabletType_MASTER || tablet.Type == topodatapb.TabletType_REPLICA {
-		instance.PromotionRule = NeutralPromoteRule
-	} else {
-		instance.PromotionRule = MustNotPromoteRule
+	// First read the current PromotionRule from candidate_database_instance.
+	{
+		latency.Start("backend")
+		err = ReadInstancePromotionRule(instance)
+		latency.Stop("backend")
+		logReadTopologyInstanceError(instanceKey, "ReadInstancePromotionRule", err)
+	}
+	// Then check if the instance wants to set a different PromotionRule.
+	// We'll set it here on their behalf so there's no race between the first
+	// time an instance is discovered, and setting a rule like "must_not".
+	if config.Config.DetectPromotionRuleQuery != "" && !isMaxScale {
+		waitGroup.Add(1)
+		go func() {
+			defer waitGroup.Done()
+			var value string
+			err := db.QueryRow(config.Config.DetectPromotionRuleQuery).Scan(&value)
+			logReadTopologyInstanceError(instanceKey, "DetectPromotionRuleQuery", err)
+			promotionRule, err := ParseCandidatePromotionRule(value)
+			logReadTopologyInstanceError(instanceKey, "ParseCandidatePromotionRule", err)
+			if err == nil {
+				// We need to update candidate_database_instance.
+				// We register the rule even if it hasn't changed,
+				// to bump the last_suggested time.
+				instance.PromotionRule = promotionRule
+				err = RegisterCandidateInstance(NewCandidateDatabaseInstance(instanceKey, promotionRule).WithCurrentTime())
+				logReadTopologyInstanceError(instanceKey, "RegisterCandidateInstance", err)
+			}
+		}()
 	}
-	err = RegisterCandidateInstance(NewCandidateDatabaseInstance(instanceKey, instance.PromotionRule).WithCurrentTime())
-	logReadTopologyInstanceError(instanceKey, "RegisterCandidateInstance", err)
-
-	// TODO(sougou): delete cluster_alias_override metadata
-	instance.SuggestedClusterAlias = fmt.Sprintf("%v:%v", tablet.Keyspace, tablet.Shard)
 
+	ReadClusterAliasOverride(instance)
+	if !isMaxScale {
+		if instance.SuggestedClusterAlias == "" {
+			// Only need to do on masters
+			if config.Config.DetectClusterAliasQuery != "" {
+				clusterAlias := ""
+				if err := db.QueryRow(config.Config.DetectClusterAliasQuery).Scan(&clusterAlias); err != nil {
+					logReadTopologyInstanceError(instanceKey, "DetectClusterAliasQuery", err)
+				} else {
+					instance.SuggestedClusterAlias = clusterAlias
+				}
+			}
+		}
+		if instance.SuggestedClusterAlias == "" {
+			// Not found by DetectClusterAliasQuery...
+			// See if a ClusterNameToAlias configuration applies
+			if clusterAlias := mappedClusterNameToAlias(instance.ClusterName); clusterAlias != "" {
+				instance.SuggestedClusterAlias = clusterAlias
+			}
+		}
+	}
 	if instance.ReplicationDepth == 0 && config.Config.DetectClusterDomainQuery != "" && !isMaxScale {
 		// Only need to do on masters
 		domainName := ""
@@ -945,6 +963,28 @@ Cleanup:
 	return nil, err
 }
 
+// ReadClusterAliasOverride reads and applies SuggestedClusterAlias based on cluster_alias_override
+func ReadClusterAliasOverride(instance *Instance) (err error) {
+	aliasOverride := ""
+	query := `
+		select
+			alias
+		from
+			cluster_alias_override
+		where
+			cluster_name = ?
+			`
+	err = db.QueryOrchestrator(query, sqlutils.Args(instance.ClusterName), func(m sqlutils.RowMap) error {
+		aliasOverride = m.GetString("alias")
+
+		return nil
+	})
+	if aliasOverride != "" {
+		instance.SuggestedClusterAlias = aliasOverride
+	}
+	return err
+}
+
 func ReadReplicationGroupPrimary(instance *Instance) (err error) {
 	query := `
 	SELECT
@@ -977,6 +1017,7 @@ func ReadReplicationGroupPrimary(instance *Instance) (err error) {
 func ReadInstanceClusterAttributes(instance *Instance) (err error) {
 	var masterOrGroupPrimaryInstanceKey InstanceKey
 	var masterOrGroupPrimaryClusterName string
+	var masterOrGroupPrimarySuggestedClusterAlias string
 	var masterOrGroupPrimaryReplicationDepth uint
 	var ancestryUUID string
 	var masterOrGroupPrimaryExecutedGtidSet string
@@ -1006,6 +1047,7 @@ func ReadInstanceClusterAttributes(instance *Instance) (err error) {
 	args := sqlutils.Args(masterOrGroupPrimaryInstanceKey.Hostname, masterOrGroupPrimaryInstanceKey.Port)
 	err = db.QueryOrchestrator(query, args, func(m sqlutils.RowMap) error {
 		masterOrGroupPrimaryClusterName = m.GetString("cluster_name")
+		masterOrGroupPrimarySuggestedClusterAlias = m.GetString("suggested_cluster_alias")
 		masterOrGroupPrimaryReplicationDepth = m.GetUint("replication_depth")
 		masterOrGroupPrimaryInstanceKey.Hostname = m.GetString("master_host")
 		masterOrGroupPrimaryInstanceKey.Port = m.GetInt("master_port")
@@ -1047,6 +1089,7 @@ func ReadInstanceClusterAttributes(instance *Instance) (err error) {
 		} // While the other stays "1"
 	}
 	instance.ClusterName = clusterName
+	instance.SuggestedClusterAlias = masterOrGroupPrimarySuggestedClusterAlias
 	instance.ReplicationDepth = replicationDepth
 	instance.IsCoMaster = isCoMaster
 	instance.AncestryUUID = ancestryUUID
@@ -1362,12 +1405,6 @@ func ReadWriteableClustersMasters() (instances [](*Instance), err error) {
 	return instances, err
 }
 
-// ReadClusterAliasInstances reads all instances of a cluster alias
-func ReadClusterAliasInstances(clusterAlias string) ([](*Instance), error) {
-	condition := `suggested_cluster_alias = ? `
-	return readInstancesByCondition(condition, sqlutils.Args(clusterAlias), "")
-}
-
 // ReadReplicaInstances reads replicas of a given master
 func ReadReplicaInstances(masterKey *InstanceKey) ([](*Instance), error) {
 	condition := `
diff --git a/go/vt/orchestrator/inst/instance_topology.go b/go/vt/orchestrator/inst/instance_topology.go
index d608493cc6..f2f787c54f 100644
--- a/go/vt/orchestrator/inst/instance_topology.go
+++ b/go/vt/orchestrator/inst/instance_topology.go
@@ -585,7 +585,7 @@ func canReplicateAssumingOracleGTID(instance, masterInstance *Instance) (canRepl
 }
 
 func instancesAreGTIDAndCompatible(instance, otherInstance *Instance) (isOracleGTID bool, isMariaDBGTID, compatible bool) {
-	isOracleGTID = (instance.SupportsOracleGTID && otherInstance.SupportsOracleGTID)
+	isOracleGTID = (instance.UsingOracleGTID && otherInstance.SupportsOracleGTID)
 	isMariaDBGTID = (instance.UsingMariaDBGTID && otherInstance.IsMariaDB())
 	compatible = isOracleGTID || isMariaDBGTID
 	return isOracleGTID, isMariaDBGTID, compatible
@@ -1007,6 +1007,16 @@ func MakeCoMaster(instanceKey *InstanceKey) (*Instance, error) {
 			goto Cleanup
 		}
 	}
+	if !master.HasReplicationCredentials {
+		// Let's try , if possible, to get credentials from replica. Best effort.
+		if replicationUser, replicationPassword, credentialsErr := ReadReplicationCredentials(&instance.Key); credentialsErr == nil {
+			log.Debugf("Got credentials from a replica. will now apply")
+			_, err = ChangeMasterCredentials(&master.Key, replicationUser, replicationPassword)
+			if err != nil {
+				goto Cleanup
+			}
+		}
+	}
 
 	if instance.AllowTLS {
 		log.Debugf("Enabling SSL replication")
@@ -2523,11 +2533,6 @@ func RegroupReplicasGTID(
 			}
 		}
 	}
-
-	if err := TabletSetMaster(candidateReplica.Key); err != nil {
-		return emptyReplicas, emptyReplicas, emptyReplicas, candidateReplica, err
-	}
-
 	moveGTIDFunc := func() error {
 		log.Debugf("RegroupReplicasGTID: working on %d replicas", len(replicasToMove))
 
diff --git a/go/vt/orchestrator/inst/instance_topology_dao.go b/go/vt/orchestrator/inst/instance_topology_dao.go
index 0282512ef3..956d7b5e78 100644
--- a/go/vt/orchestrator/inst/instance_topology_dao.go
+++ b/go/vt/orchestrator/inst/instance_topology_dao.go
@@ -389,6 +389,10 @@ func StopReplication(instanceKey *InstanceKey) (*Instance, error) {
 	if err != nil {
 		return instance, log.Errore(err)
 	}
+
+	if !instance.IsReplica() {
+		return instance, fmt.Errorf("instance is not a replica: %+v", instanceKey)
+	}
 	_, err = ExecInstance(instanceKey, `stop slave`)
 	if err != nil {
 		// Patch; current MaxScale behavior for STOP SLAVE is to throw an error if replica already stopped.
@@ -582,6 +586,37 @@ func EnableSemiSync(instanceKey *InstanceKey, master, replica bool) error {
 	return err
 }
 
+// ChangeMasterCredentials issues a CHANGE MASTER TO... MASTER_USER=, MASTER_PASSWORD=...
+func ChangeMasterCredentials(instanceKey *InstanceKey, masterUser string, masterPassword string) (*Instance, error) {
+	instance, err := ReadTopologyInstance(instanceKey)
+	if err != nil {
+		return instance, log.Errore(err)
+	}
+	if masterUser == "" {
+		return instance, log.Errorf("Empty user in ChangeMasterCredentials() for %+v", *instanceKey)
+	}
+
+	if instance.ReplicationThreadsExist() && !instance.ReplicationThreadsStopped() {
+		return instance, fmt.Errorf("ChangeMasterTo: Cannot change master on: %+v because replication is running", *instanceKey)
+	}
+	log.Debugf("ChangeMasterTo: will attempt changing master credentials on %+v", *instanceKey)
+
+	if *config.RuntimeCLIFlags.Noop {
+		return instance, fmt.Errorf("noop: aborting CHANGE MASTER TO operation on %+v; signalling error but nothing went wrong.", *instanceKey)
+	}
+	_, err = ExecInstance(instanceKey, "change master to master_user=?, master_password=?",
+		masterUser, masterPassword)
+
+	if err != nil {
+		return instance, log.Errore(err)
+	}
+
+	log.Infof("ChangeMasterTo: Changed master credentials on %+v", *instanceKey)
+
+	instance, err = ReadTopologyInstance(instanceKey)
+	return instance, err
+}
+
 // EnableMasterSSL issues CHANGE MASTER TO MASTER_SSL=1
 func EnableMasterSSL(instanceKey *InstanceKey) (*Instance, error) {
 	instance, err := ReadTopologyInstance(instanceKey)
@@ -626,9 +661,7 @@ func workaroundBug83713(instanceKey *InstanceKey) {
 }
 
 // ChangeMasterTo changes the given instance's master according to given input.
-// TODO(sougou): deprecate ReplicationCredentialsQuery, and all other credential discovery.
 func ChangeMasterTo(instanceKey *InstanceKey, masterKey *InstanceKey, masterBinlogCoordinates *BinlogCoordinates, skipUnresolve bool, gtidHint OperationGTIDHint) (*Instance, error) {
-	user, password := config.Config.MySQLReplicaUser, config.Config.MySQLReplicaPassword
 	instance, err := ReadTopologyInstance(instanceKey)
 	if err != nil {
 		return instance, log.Errore(err)
@@ -663,16 +696,16 @@ func ChangeMasterTo(instanceKey *InstanceKey, masterKey *InstanceKey, masterBinl
 	if instance.UsingMariaDBGTID && gtidHint != GTIDHintDeny {
 		// Keep on using GTID
 		changeMasterFunc = func() error {
-			_, err := ExecInstance(instanceKey, "change master to master_user=?, master_password=?, master_host=?, master_port=?",
-				user, password, changeToMasterKey.Hostname, changeToMasterKey.Port)
+			_, err := ExecInstance(instanceKey, "change master to master_host=?, master_port=?",
+				changeToMasterKey.Hostname, changeToMasterKey.Port)
 			return err
 		}
 		changedViaGTID = true
 	} else if instance.UsingMariaDBGTID && gtidHint == GTIDHintDeny {
 		// Make sure to not use GTID
 		changeMasterFunc = func() error {
-			_, err = ExecInstance(instanceKey, "change master to master_user=?, master_password=?, master_host=?, master_port=?, master_log_file=?, master_log_pos=?, master_use_gtid=no",
-				user, password, changeToMasterKey.Hostname, changeToMasterKey.Port, masterBinlogCoordinates.LogFile, masterBinlogCoordinates.LogPos)
+			_, err = ExecInstance(instanceKey, "change master to master_host=?, master_port=?, master_log_file=?, master_log_pos=?, master_use_gtid=no",
+				changeToMasterKey.Hostname, changeToMasterKey.Port, masterBinlogCoordinates.LogFile, masterBinlogCoordinates.LogPos)
 			return err
 		}
 	} else if instance.IsMariaDB() && gtidHint == GTIDHintForce {
@@ -687,39 +720,39 @@ func ChangeMasterTo(instanceKey *InstanceKey, masterKey *InstanceKey, masterBinl
 			mariadbGTIDHint = "current_pos"
 		}
 		changeMasterFunc = func() error {
-			_, err = ExecInstance(instanceKey, fmt.Sprintf("change master to master_user=?, master_password=?, master_host=?, master_port=?, master_use_gtid=%s", mariadbGTIDHint),
-				user, password, changeToMasterKey.Hostname, changeToMasterKey.Port)
+			_, err = ExecInstance(instanceKey, fmt.Sprintf("change master to master_host=?, master_port=?, master_use_gtid=%s", mariadbGTIDHint),
+				changeToMasterKey.Hostname, changeToMasterKey.Port)
 			return err
 		}
 		changedViaGTID = true
 	} else if instance.UsingOracleGTID && gtidHint != GTIDHintDeny {
 		// Is Oracle; already uses GTID; keep using it.
 		changeMasterFunc = func() error {
-			_, err = ExecInstance(instanceKey, "change master to master_user=?, master_password=?, master_host=?, master_port=?",
-				user, password, changeToMasterKey.Hostname, changeToMasterKey.Port)
+			_, err = ExecInstance(instanceKey, "change master to master_host=?, master_port=?",
+				changeToMasterKey.Hostname, changeToMasterKey.Port)
 			return err
 		}
 		changedViaGTID = true
 	} else if instance.UsingOracleGTID && gtidHint == GTIDHintDeny {
 		// Is Oracle; already uses GTID
 		changeMasterFunc = func() error {
-			_, err = ExecInstance(instanceKey, "change master to master_user=?, master_password=?, master_host=?, master_port=?, master_log_file=?, master_log_pos=?, master_auto_position=0",
-				user, password, changeToMasterKey.Hostname, changeToMasterKey.Port, masterBinlogCoordinates.LogFile, masterBinlogCoordinates.LogPos)
+			_, err = ExecInstance(instanceKey, "change master to master_host=?, master_port=?, master_log_file=?, master_log_pos=?, master_auto_position=0",
+				changeToMasterKey.Hostname, changeToMasterKey.Port, masterBinlogCoordinates.LogFile, masterBinlogCoordinates.LogPos)
 			return err
 		}
 	} else if instance.SupportsOracleGTID && gtidHint == GTIDHintForce {
 		// Is Oracle; not using GTID right now; turn into GTID
 		changeMasterFunc = func() error {
-			_, err = ExecInstance(instanceKey, "change master to master_user=?, master_password=?, master_host=?, master_port=?, master_auto_position=1",
-				user, password, changeToMasterKey.Hostname, changeToMasterKey.Port)
+			_, err = ExecInstance(instanceKey, "change master to master_host=?, master_port=?, master_auto_position=1",
+				changeToMasterKey.Hostname, changeToMasterKey.Port)
 			return err
 		}
 		changedViaGTID = true
 	} else {
 		// Normal binlog file:pos
 		changeMasterFunc = func() error {
-			_, err = ExecInstance(instanceKey, "change master to master_user=?, master_password=?, master_host=?, master_port=?, master_log_file=?, master_log_pos=?",
-				user, password, changeToMasterKey.Hostname, changeToMasterKey.Port, masterBinlogCoordinates.LogFile, masterBinlogCoordinates.LogPos)
+			_, err = ExecInstance(instanceKey, "change master to master_host=?, master_port=?, master_log_file=?, master_log_pos=?",
+				changeToMasterKey.Hostname, changeToMasterKey.Port, masterBinlogCoordinates.LogFile, masterBinlogCoordinates.LogPos)
 			return err
 		}
 	}
@@ -947,6 +980,36 @@ func MasterPosWait(instanceKey *InstanceKey, binlogCoordinates *BinlogCoordinate
 	return instance, err
 }
 
+// Attempt to read and return replication credentials from the mysql.slave_master_info system table
+func ReadReplicationCredentials(instanceKey *InstanceKey) (replicationUser string, replicationPassword string, err error) {
+	if config.Config.ReplicationCredentialsQuery != "" {
+		err = ScanInstanceRow(instanceKey, config.Config.ReplicationCredentialsQuery, &replicationUser, &replicationPassword)
+		if err == nil && replicationUser == "" {
+			err = fmt.Errorf("Empty username retrieved by ReplicationCredentialsQuery")
+		}
+		if err == nil {
+			return replicationUser, replicationPassword, nil
+		}
+		log.Errore(err)
+	}
+	// Didn't get credentials from ReplicationCredentialsQuery, or ReplicationCredentialsQuery doesn't exist in the first place?
+	// We brute force our way through mysql.slave_master_info
+	{
+		query := `
+			select
+				ifnull(max(User_name), '') as user,
+				ifnull(max(User_password), '') as password
+			from
+				mysql.slave_master_info
+		`
+		err = ScanInstanceRow(instanceKey, query, &replicationUser, &replicationPassword)
+		if err == nil && replicationUser == "" {
+			err = fmt.Errorf("Empty username found in mysql.slave_master_info")
+		}
+	}
+	return replicationUser, replicationPassword, log.Errore(err)
+}
+
 // SetReadOnly sets or clears the instance's global read_only variable
 func SetReadOnly(instanceKey *InstanceKey, readOnly bool) (*Instance, error) {
 	instance, err := ReadTopologyInstance(instanceKey)
diff --git a/go/vt/orchestrator/inst/tablet_dao.go b/go/vt/orchestrator/inst/tablet_dao.go
deleted file mode 100644
index 7aaeb15300..0000000000
--- a/go/vt/orchestrator/inst/tablet_dao.go
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-Copyright 2020 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.
-*/
-
-package inst
-
-import (
-	"context"
-	"errors"
-
-	"github.com/golang/protobuf/proto"
-	"vitess.io/vitess/go/vt/logutil"
-	"vitess.io/vitess/go/vt/orchestrator/db"
-	"vitess.io/vitess/go/vt/orchestrator/external/golib/log"
-	"vitess.io/vitess/go/vt/orchestrator/external/golib/sqlutils"
-	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
-	"vitess.io/vitess/go/vt/topo"
-	"vitess.io/vitess/go/vt/vttablet/tmclient"
-)
-
-// TopoServ is the connection to the topo server.
-var TopoServ *topo.Server
-
-// ErrTabletAliasNil is a fixed error message.
-var ErrTabletAliasNil = errors.New("tablet alias is nil")
-
-// TabletSetMaster designates the tablet that owns an instance as the master.
-func TabletSetMaster(instanceKey InstanceKey) error {
-	if instanceKey.Hostname == "" {
-		return errors.New("can't set tablet to master: instance is unspecified")
-	}
-	tablet, err := ReadTablet(instanceKey)
-	if err != nil {
-		return err
-	}
-	tmc := tmclient.NewTabletManagerClient()
-	if err := tmc.ChangeType(context.TODO(), tablet, topodatapb.TabletType_MASTER); err != nil {
-		return err
-	}
-	ti, err := TopoServ.GetTablet(context.TODO(), tablet.Alias)
-	if err != nil {
-		return log.Errore(err)
-	}
-	if err := SaveTablet(ti.Tablet); err != nil {
-		log.Errore(err)
-	}
-	return nil
-}
-
-// ReadTablet reads the vitess tablet record.
-func ReadTablet(instanceKey InstanceKey) (*topodatapb.Tablet, error) {
-	query := `
-		select
-			info
-		from
-			vitess_tablet
-		where hostname=? and port=?
-		`
-	args := sqlutils.Args(instanceKey.Hostname, instanceKey.Port)
-	tablet := &topodatapb.Tablet{}
-	err := db.QueryOrchestrator(query, args, func(row sqlutils.RowMap) error {
-		return proto.UnmarshalText(row.GetString("info"), tablet)
-	})
-	if err != nil {
-		return nil, err
-	}
-	if tablet.Alias == nil {
-		return nil, ErrTabletAliasNil
-	}
-	return tablet, nil
-}
-
-// SaveTablet saves the tablet record against the instanceKey.
-func SaveTablet(tablet *topodatapb.Tablet) error {
-	_, err := db.ExecOrchestrator(`
-		replace
-			into vitess_tablet (
-				hostname, port, cell, tablet_type, master_timestamp, info
-			) values (
-				?, ?, ?, ?, ?, ?
-			)
-		`,
-		tablet.MysqlHostname,
-		int(tablet.MysqlPort),
-		tablet.Alias.Cell,
-		int(tablet.Type),
-		logutil.ProtoToTime(tablet.MasterTermStartTime),
-		proto.CompactTextString(tablet),
-	)
-	return err
-}
diff --git a/go/vt/orchestrator/logic/orchestrator.go b/go/vt/orchestrator/logic/orchestrator.go
index be70b17b04..b44017fac2 100644
--- a/go/vt/orchestrator/logic/orchestrator.go
+++ b/go/vt/orchestrator/logic/orchestrator.go
@@ -492,7 +492,6 @@ func ContinuousDiscovery() {
 	raftCaretakingTick := time.Tick(10 * time.Minute)
 	recoveryTick := time.Tick(time.Duration(config.RecoveryPollSeconds) * time.Second)
 	autoPseudoGTIDTick := time.Tick(time.Duration(config.PseudoGTIDIntervalSeconds) * time.Second)
-	tabletTopoTick := OpenTabletDiscovery()
 	var recoveryEntrance int64
 	var snapshotTopologiesTick <-chan time.Time
 	if config.Config.SnapshotTopologiesIntervalHours > 0 {
@@ -616,8 +615,6 @@ func ContinuousDiscovery() {
 					go inst.SnapshotTopologies()
 				}
 			}()
-		case <-tabletTopoTick:
-			go RefreshTablets()
 		}
 	}
 }
diff --git a/go/vt/orchestrator/logic/tablet_discovery.go b/go/vt/orchestrator/logic/tablet_discovery.go
deleted file mode 100644
index 9bcdebd16f..0000000000
--- a/go/vt/orchestrator/logic/tablet_discovery.go
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
-Copyright 2020 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.
-*/
-
-package logic
-
-import (
-	"context"
-	"errors"
-	"fmt"
-	"sync"
-	"time"
-
-	"github.com/golang/protobuf/proto"
-	"vitess.io/vitess/go/vt/orchestrator/db"
-	"vitess.io/vitess/go/vt/orchestrator/external/golib/log"
-	"vitess.io/vitess/go/vt/orchestrator/external/golib/sqlutils"
-	"vitess.io/vitess/go/vt/orchestrator/inst"
-	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
-	"vitess.io/vitess/go/vt/topo"
-	"vitess.io/vitess/go/vt/topotools"
-	"vitess.io/vitess/go/vt/vttablet/tmclient"
-)
-
-var (
-	ts *topo.Server
-)
-
-// OpenTabletDiscovery opens the vitess topo if enables and returns a ticker
-// channel for polling.
-func OpenTabletDiscovery() <-chan time.Time {
-	// TODO(sougou): If there's a shutdown signal, we have to close the topo.
-	ts = topo.Open()
-	// TODO(sougou): remove ts and push some functions into inst.
-	inst.TopoServ = ts
-	// Clear existing cache and perform a new refresh.
-	if _, err := db.ExecOrchestrator("delete from vitess_tablet"); err != nil {
-		log.Errore(err)
-	}
-	refreshTabletsUsing(func(instanceKey *inst.InstanceKey) {
-		_ = inst.InjectSeed(instanceKey)
-	})
-	// TODO(sougou): parameterize poll interval.
-	return time.Tick(15 * time.Second) //nolint SA1015: using time.Tick leaks the underlying ticker
-}
-
-// RefreshTablets reloads the tablets from topo.
-func RefreshTablets() {
-	refreshTabletsUsing(func(instanceKey *inst.InstanceKey) {
-		DiscoverInstance(*instanceKey)
-	})
-}
-
-func refreshTabletsUsing(loader func(instanceKey *inst.InstanceKey)) {
-	if !IsLeaderOrActive() {
-		return
-	}
-	cells, err := ts.GetKnownCells(context.TODO())
-	if err != nil {
-		log.Errore(err)
-		return
-	}
-
-	var wg sync.WaitGroup
-	for _, cell := range cells {
-		wg.Add(1)
-		go func(cell string) {
-			defer wg.Done()
-			refreshTabletsInCell(cell, loader)
-		}(cell)
-	}
-	wg.Wait()
-}
-
-func refreshTabletsInCell(cell string, loader func(instanceKey *inst.InstanceKey)) {
-	latestInstances := make(map[inst.InstanceKey]bool)
-	tablets, err := topotools.GetAllTablets(context.TODO(), ts, cell)
-	if err != nil {
-		log.Errorf("Error fetching topo info for cell %v: %v", cell, err)
-		return
-	}
-
-	// Discover new tablets.
-	// TODO(sougou): enhance this to work with multi-schema,
-	// where each instanceKey can have multiple tablets.
-	for _, tabletInfo := range tablets {
-		tablet := tabletInfo.Tablet
-		if tablet.MysqlHostname == "" {
-			continue
-		}
-		if tablet.Type != topodatapb.TabletType_MASTER && !topo.IsReplicaType(tablet.Type) {
-			continue
-		}
-		instanceKey := inst.InstanceKey{
-			Hostname: tablet.MysqlHostname,
-			Port:     int(tablet.MysqlPort),
-		}
-		latestInstances[instanceKey] = true
-		old, err := inst.ReadTablet(instanceKey)
-		if err != nil && err != inst.ErrTabletAliasNil {
-			log.Errore(err)
-			continue
-		}
-		if proto.Equal(tablet, old) {
-			continue
-		}
-		if err := inst.SaveTablet(tablet); err != nil {
-			log.Errore(err)
-			continue
-		}
-		loader(&instanceKey)
-		log.Infof("Discovered: %v", tablet)
-	}
-
-	// Forget tablets that were removed.
-	toForget := make(map[inst.InstanceKey]*topodatapb.Tablet)
-	query := "select hostname, port, info from vitess_tablet where cell = ?"
-	err = db.QueryOrchestrator(query, sqlutils.Args(cell), func(row sqlutils.RowMap) error {
-		curKey := inst.InstanceKey{
-			Hostname: row.GetString("hostname"),
-			Port:     row.GetInt("port"),
-		}
-		if !latestInstances[curKey] {
-			tablet := &topodatapb.Tablet{}
-			if err := proto.UnmarshalText(row.GetString("info"), tablet); err != nil {
-				log.Errore(err)
-				return nil
-			}
-			toForget[curKey] = tablet
-		}
-		return nil
-	})
-	if err != nil {
-		log.Errore(err)
-	}
-	for instanceKey, tablet := range toForget {
-		log.Infof("Forgeting: %v", tablet)
-		_, err := db.ExecOrchestrator(`
-					delete
-						from vitess_tablet
-					where
-						hostname=? and port=?`,
-			instanceKey.Hostname,
-			instanceKey.Port,
-		)
-		if err != nil {
-			log.Errore(err)
-		}
-		if err := inst.ForgetInstance(&instanceKey); err != nil {
-			log.Errore(err)
-		}
-	}
-}
-
-// LockShard locks the keyspace-shard preventing others from performing conflicting actions.
-func LockShard(instanceKey inst.InstanceKey) (func(*error), error) {
-	if instanceKey.Hostname == "" {
-		return nil, errors.New("Can't lock shard: instance is unspecified")
-	}
-
-	tablet, err := inst.ReadTablet(instanceKey)
-	if err != nil {
-		return nil, err
-	}
-	_, unlock, err := ts.LockShard(context.TODO(), tablet.Keyspace, tablet.Shard, "Orc Recovery")
-	return unlock, err
-}
-
-// TabletRefresh refreshes the tablet info.
-func TabletRefresh(instanceKey inst.InstanceKey) error {
-	tablet, err := inst.ReadTablet(instanceKey)
-	if err != nil {
-		return err
-	}
-	ti, err := ts.GetTablet(context.TODO(), tablet.Alias)
-	if err != nil {
-		return err
-	}
-	return inst.SaveTablet(ti.Tablet)
-}
-
-// TabletDemoteMaster requests the master tablet to stop accepting transactions.
-func TabletDemoteMaster(instanceKey inst.InstanceKey) error {
-	return tabletDemoteMaster(instanceKey, true)
-}
-
-// TabletUndoDemoteMaster requests the master tablet to undo the demote.
-func TabletUndoDemoteMaster(instanceKey inst.InstanceKey) error {
-	return tabletDemoteMaster(instanceKey, false)
-}
-
-func tabletDemoteMaster(instanceKey inst.InstanceKey, forward bool) error {
-	if instanceKey.Hostname == "" {
-		return errors.New("Can't demote/undo master: instance is unspecified")
-	}
-	tablet, err := inst.ReadTablet(instanceKey)
-	if err != nil {
-		return err
-	}
-	tmc := tmclient.NewTabletManagerClient()
-	if forward {
-		_, err = tmc.DemoteMaster(context.TODO(), tablet)
-	} else {
-		err = tmc.UndoDemoteMaster(context.TODO(), tablet)
-	}
-	return err
-}
-
-func ShardMaster(instanceKey *inst.InstanceKey) (masterKey *inst.InstanceKey, err error) {
-	tablet, err := inst.ReadTablet(*instanceKey)
-	if err != nil {
-		return nil, err
-	}
-	si, err := ts.GetShard(context.TODO(), tablet.Keyspace, tablet.Shard)
-	if err != nil {
-		return nil, err
-	}
-	if !si.HasMaster() {
-		return nil, fmt.Errorf("no master tablet for shard %v/%v", tablet.Keyspace, tablet.Shard)
-	}
-	master, err := ts.GetTablet(context.TODO(), si.MasterAlias)
-	if err != nil {
-		return nil, err
-	}
-	return &inst.InstanceKey{
-		Hostname: master.MysqlHostname,
-		Port:     int(master.MysqlPort),
-	}, nil
-}
diff --git a/go/vt/orchestrator/logic/topology_recovery.go b/go/vt/orchestrator/logic/topology_recovery.go
index 23800675dd..27e871ff1a 100644
--- a/go/vt/orchestrator/logic/topology_recovery.go
+++ b/go/vt/orchestrator/logic/topology_recovery.go
@@ -564,8 +564,7 @@ func recoverDeadMaster(topologyRecovery *TopologyRecovery, candidateInstanceKey
 	}
 
 	func() error {
-		// TODO(sougou): Commented out: this downtime feels a little aggressive.
-		//inst.BeginDowntime(inst.NewDowntime(failedInstanceKey, inst.GetMaintenanceOwner(), inst.DowntimeLostInRecoveryMessage, time.Duration(config.LostInRecoveryDowntimeSeconds)*time.Second))
+		inst.BeginDowntime(inst.NewDowntime(failedInstanceKey, inst.GetMaintenanceOwner(), inst.DowntimeLostInRecoveryMessage, time.Duration(config.LostInRecoveryDowntimeSeconds)*time.Second))
 		acknowledgeInstanceFailureDetection(&analysisEntry.AnalyzedInstanceKey)
 		for _, replica := range lostReplicas {
 			replica := replica
@@ -827,20 +826,8 @@ func checkAndRecoverDeadMaster(analysisEntry inst.ReplicationAnalysis, candidate
 		AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another RecoverDeadMaster.", analysisEntry.AnalyzedInstanceKey))
 		return false, nil, err
 	}
-	log.Infof("Analysis: %v, deadmaster %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceKey)
 
 	// That's it! We must do recovery!
-	// TODO(sougou): This function gets called by GracefulMasterTakeover which may
-	// need to obtain shard lock before getting here.
-	unlock, err := LockShard(analysisEntry.AnalyzedInstanceKey)
-	if err != nil {
-		log.Infof("CheckAndRecover: Analysis: %+v, InstanceKey: %+v, candidateInstanceKey: %+v, "+
-			"skipProcesses: %v: NOT detecting/recovering host, could not obtain shard lock (%v)",
-			analysisEntry.Analysis, analysisEntry.AnalyzedInstanceKey, candidateInstanceKey, skipProcesses, err)
-		return false, nil, err
-	}
-	defer unlock(&err)
-
 	AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("will handle DeadMaster event on %+v", analysisEntry.ClusterDetails.ClusterName))
 	recoverDeadMasterCounter.Inc(1)
 	recoveryAttempted, promotedReplica, lostReplicas, err := recoverDeadMaster(topologyRecovery, candidateInstanceKey, skipProcesses)
@@ -891,27 +878,30 @@ func checkAndRecoverDeadMaster(analysisEntry inst.ReplicationAnalysis, candidate
 		AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("RecoverDeadMaster: successfully promoted %+v", promotedReplica.Key))
 		AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadMaster: promoted server coordinates: %+v", promotedReplica.SelfBinlogCoordinates))
 
-		AuditTopologyRecovery(topologyRecovery, "- RecoverDeadMaster: will apply MySQL changes to promoted master")
-		{
-			_, err := inst.ResetReplicationOperation(&promotedReplica.Key)
-			if err != nil {
-				// Ugly, but this is important. Let's give it another try
-				_, err = inst.ResetReplicationOperation(&promotedReplica.Key)
+		if config.Config.ApplyMySQLPromotionAfterMasterFailover || analysisEntry.CommandHint == inst.GracefulMasterTakeoverCommandHint {
+			// on GracefulMasterTakeoverCommandHint it makes utter sense to RESET SLAVE ALL and read_only=0, and there is no sense in not doing so.
+			AuditTopologyRecovery(topologyRecovery, "- RecoverDeadMaster: will apply MySQL changes to promoted master")
+			{
+				_, err := inst.ResetReplicationOperation(&promotedReplica.Key)
+				if err != nil {
+					// Ugly, but this is important. Let's give it another try
+					_, err = inst.ResetReplicationOperation(&promotedReplica.Key)
+				}
+				AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadMaster: applying RESET SLAVE ALL on promoted master: success=%t", (err == nil)))
+				if err != nil {
+					AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadMaster: NOTE that %+v is promoted even though SHOW SLAVE STATUS may still show it has a master", promotedReplica.Key))
+				}
 			}
-			AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadMaster: applying RESET SLAVE ALL on promoted master: success=%t", (err == nil)))
-			if err != nil {
-				AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadMaster: NOTE that %+v is promoted even though SHOW SLAVE STATUS may still show it has a master", promotedReplica.Key))
+			{
+				_, err := inst.SetReadOnly(&promotedReplica.Key, false)
+				AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadMaster: applying read-only=0 on promoted master: success=%t", (err == nil)))
 			}
+			// Let's attempt, though we won't necessarily succeed, to set old master as read-only
+			go func() {
+				_, err := inst.SetReadOnly(&analysisEntry.AnalyzedInstanceKey, true)
+				AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadMaster: applying read-only=1 on demoted master: success=%t", (err == nil)))
+			}()
 		}
-		{
-			_, err := inst.SetReadOnly(&promotedReplica.Key, false)
-			AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadMaster: applying read-only=0 on promoted master: success=%t", (err == nil)))
-		}
-		// Let's attempt, though we won't necessarily succeed, to set old master as read-only
-		go func() {
-			_, err := inst.SetReadOnly(&analysisEntry.AnalyzedInstanceKey, true)
-			AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadMaster: applying read-only=1 on demoted master: success=%t", (err == nil)))
-		}()
 
 		kvPairs := inst.GetClusterMasterKVPairs(analysisEntry.ClusterDetails.ClusterAlias, &promotedReplica.Key)
 		AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("Writing KV %+v", kvPairs))
@@ -1530,15 +1520,6 @@ func getCheckAndRecoverFunction(analysisCode inst.AnalysisCode, analyzedInstance
 		} else {
 			return checkAndRecoverLockedSemiSyncMaster, true
 		}
-	// topo
-	case inst.ClusterHasNoMaster:
-		return electNewMaster, true
-	case inst.MasterHasMaster:
-		return fixClusterAndMaster, true
-	case inst.MasterIsReadOnly:
-		return fixMaster, true
-	case inst.NotConnectedToMaster, inst.ConnectedToWrongMaster, inst.ReplicationStopped, inst.ReplicaIsWritable:
-		return fixReplica, false
 	// intermediate master
 	case inst.DeadIntermediateMaster:
 		return checkAndRecoverDeadIntermediateMaster, true
@@ -1892,7 +1873,7 @@ func getGracefulMasterTakeoverDesignatedInstance(clusterMasterKey *inst.Instance
 // It expects that replica to have no siblings.
 // This function is graceful in that it will first lock down the master, then wait
 // for the designated replica to catch up with last position.
-// It will point old master at the newly promoted master at the correct coordinates.
+// It will point old master at the newly promoted master at the correct coordinates, but will not start replication.
 func GracefulMasterTakeover(clusterName string, designatedKey *inst.InstanceKey, auto bool) (topologyRecovery *TopologyRecovery, promotedMasterCoordinates *inst.BinlogCoordinates, err error) {
 	clusterMasters, err := inst.ReadClusterMaster(clusterName)
 	if err != nil {
@@ -1964,6 +1945,8 @@ func GracefulMasterTakeover(clusterName string, designatedKey *inst.InstanceKey,
 	}
 	log.Infof("GracefulMasterTakeover: Will demote %+v and promote %+v instead", clusterMaster.Key, designatedInstance.Key)
 
+	replicationUser, replicationPassword, replicationCredentialsError := inst.ReadReplicationCredentials(&designatedInstance.Key)
+
 	analysisEntry, err := forceAnalysisEntry(clusterName, inst.DeadMaster, inst.GracefulMasterTakeoverCommandHint, &clusterMaster.Key)
 	if err != nil {
 		return nil, nil, err
@@ -1976,8 +1959,8 @@ func GracefulMasterTakeover(clusterName string, designatedKey *inst.InstanceKey,
 		return nil, nil, fmt.Errorf("Failed running PreGracefulTakeoverProcesses: %+v", err)
 	}
 
-	log.Infof("GracefulMasterTakeover: invoking TabletDemoteMaster on %+v", clusterMaster.Key)
-	if err := TabletDemoteMaster(clusterMaster.Key); err != nil {
+	log.Infof("GracefulMasterTakeover: Will set %+v as read_only", clusterMaster.Key)
+	if clusterMaster, err = inst.SetReadOnly(&clusterMaster.Key, true); err != nil {
 		return nil, nil, err
 	}
 	demotedMasterSelfBinlogCoordinates := &clusterMaster.SelfBinlogCoordinates
@@ -1999,11 +1982,10 @@ func GracefulMasterTakeover(clusterName string, designatedKey *inst.InstanceKey,
 		return nil, nil, fmt.Errorf("GracefulMasterTakeover: recovery attempted but with no results. This should not happen")
 	}
 	if topologyRecovery.SuccessorKey == nil {
-		// Promotion failed. Undo.
-		log.Infof("GracefulMasterTakeover: Invoking tabletUndoDemoteMaster on %+v", clusterMaster.Key)
-		if err := TabletUndoDemoteMaster(clusterMaster.Key); err != nil {
-			log.Errore(err)
-		}
+		// Promotion fails.
+		// Undo setting read-only on original master.
+		inst.SetReadOnly(&clusterMaster.Key, false)
+		return nil, nil, fmt.Errorf("GracefulMasterTakeover: Recovery attempted yet no replica promoted; err=%+v", err)
 	}
 	var gtidHint inst.OperationGTIDHint = inst.GTIDHintNeutral
 	if topologyRecovery.RecoveryType == MasterRecoveryGTID {
@@ -2013,9 +1995,17 @@ func GracefulMasterTakeover(clusterName string, designatedKey *inst.InstanceKey,
 	if !clusterMaster.SelfBinlogCoordinates.Equals(demotedMasterSelfBinlogCoordinates) {
 		log.Errorf("GracefulMasterTakeover: sanity problem. Demoted master's coordinates changed from %+v to %+v while supposed to have been frozen", *demotedMasterSelfBinlogCoordinates, clusterMaster.SelfBinlogCoordinates)
 	}
-	_, startReplicationErr := inst.StartReplication(&clusterMaster.Key)
-	if err == nil {
-		err = startReplicationErr
+	if !clusterMaster.HasReplicationCredentials && replicationCredentialsError == nil {
+		_, credentialsErr := inst.ChangeMasterCredentials(&clusterMaster.Key, replicationUser, replicationPassword)
+		if err == nil {
+			err = credentialsErr
+		}
+	}
+	if auto {
+		_, startReplicationErr := inst.StartReplication(&clusterMaster.Key)
+		if err == nil {
+			err = startReplicationErr
+		}
 	}
 
 	if designatedInstance.AllowTLS {
@@ -2028,159 +2018,3 @@ func GracefulMasterTakeover(clusterName string, designatedKey *inst.InstanceKey,
 
 	return topologyRecovery, promotedMasterCoordinates, err
 }
-
-// electNewMaster elects a new master while none were present before.
-func electNewMaster(analysisEntry inst.ReplicationAnalysis, candidateInstanceKey *inst.InstanceKey, forceInstanceRecovery bool, skipProcesses bool) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) {
-	topologyRecovery, err = AttemptRecoveryRegistration(&analysisEntry, false, true)
-	if topologyRecovery == nil {
-		AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another electNewMaster.", analysisEntry.AnalyzedInstanceKey))
-		return false, nil, err
-	}
-	log.Infof("Analysis: %v, will elect a new master: %v", analysisEntry.Analysis, analysisEntry.SuggestedClusterAlias)
-
-	unlock, err := LockShard(analysisEntry.AnalyzedInstanceKey)
-	if err != nil {
-		log.Infof("CheckAndRecover: Analysis: %+v, InstanceKey: %+v, candidateInstanceKey: %+v, "+
-			"skipProcesses: %v: NOT detecting/recovering host, could not obtain shard lock (%v)",
-			analysisEntry.Analysis, analysisEntry.AnalyzedInstanceKey, candidateInstanceKey, skipProcesses, err)
-		return false, topologyRecovery, err
-	}
-	defer unlock(&err)
-
-	replicas, err := inst.ReadClusterAliasInstances(analysisEntry.SuggestedClusterAlias)
-	if err != nil {
-		return false, topologyRecovery, err
-	}
-	// TODO(sougou): this is not reliable, because of the timeout.
-	replicas = inst.StopReplicasNicely(replicas, time.Duration(config.Config.InstanceBulkOperationsWaitTimeoutSeconds)*time.Second)
-	if len(replicas) == 0 {
-		return false, topologyRecovery, fmt.Errorf("no instances in cluster %v", analysisEntry.SuggestedClusterAlias)
-	}
-
-	// Find an initial candidate
-	var candidate *inst.Instance
-	for _, replica := range replicas {
-		// TODO(sougou): this needs to do more. see inst.chooseCandidateReplica
-		if !inst.IsBannedFromBeingCandidateReplica(replica) {
-			candidate = replica
-			break
-		}
-	}
-	if candidate == nil {
-		err := fmt.Errorf("no candidate qualifies to be a master")
-		AuditTopologyRecovery(topologyRecovery, err.Error())
-		return true, topologyRecovery, err
-	}
-
-	// Compare the current candidate with the rest to see if other instances can be
-	// moved under. If not, see if the other intance can become a candidate instead.
-	for _, replica := range replicas {
-		if replica == candidate {
-			continue
-		}
-		if err := inst.CheckMoveViaGTID(replica, candidate); err != nil {
-			if err := inst.CheckMoveViaGTID(candidate, replica); err != nil {
-				return false, topologyRecovery, fmt.Errorf("instances are not compatible: %+v %+v: %v", candidate, replica, err)
-			} else {
-				// Make sure the new candidate meets the requirements.
-				if !inst.IsBannedFromBeingCandidateReplica(replica) {
-					candidate = replica
-				}
-			}
-		}
-	}
-
-	if err := inst.TabletSetMaster(candidate.Key); err != nil {
-		return true, topologyRecovery, err
-	}
-	// TODO(sougou): parallelize
-	for _, replica := range replicas {
-		if replica.Key == candidate.Key {
-			continue
-		}
-		if _, err := inst.MoveBelowGTID(&replica.Key, &candidate.Key); err != nil {
-			return false, topologyRecovery, err
-		}
-	}
-	if _, err := inst.SetReadOnly(&candidate.Key, false); err != nil {
-		return false, topologyRecovery, err
-	}
-	return true, topologyRecovery, nil
-}
-
-// fixClusterAndMaster performs a traditional vitess PlannedReparentShard.
-func fixClusterAndMaster(analysisEntry inst.ReplicationAnalysis, candidateInstanceKey *inst.InstanceKey, forceInstanceRecovery bool, skipProcesses bool) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) {
-	topologyRecovery, err = AttemptRecoveryRegistration(&analysisEntry, false, true)
-	if topologyRecovery == nil {
-		AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another fixClusterAndMaster.", analysisEntry.AnalyzedInstanceKey))
-		return false, nil, err
-	}
-	log.Infof("Analysis: %v, will fix incorrect mastership %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceKey)
-
-	// Reset replication on current master. This will prevent the comaster code-path.
-	// TODO(sougou): this should probably done while holding a lock.
-	_, err = inst.ResetReplicationOperation(&analysisEntry.AnalyzedInstanceKey)
-	if err != nil {
-		return false, topologyRecovery, err
-	}
-
-	altAnalysis, err := forceAnalysisEntry(analysisEntry.ClusterDetails.ClusterName, inst.DeadMaster, "", &analysisEntry.AnalyzedInstanceMasterKey)
-	if err != nil {
-		return false, topologyRecovery, err
-	}
-	recoveryAttempted, topologyRecovery, err = ForceExecuteRecovery(altAnalysis, &analysisEntry.AnalyzedInstanceKey, false)
-	if err != nil {
-		return recoveryAttempted, topologyRecovery, err
-	}
-	if err := TabletRefresh(analysisEntry.AnalyzedInstanceKey); err != nil {
-		log.Errore(err)
-	}
-	return recoveryAttempted, topologyRecovery, err
-}
-
-// fixMaster sets the master as read-write.
-func fixMaster(analysisEntry inst.ReplicationAnalysis, candidateInstanceKey *inst.InstanceKey, forceInstanceRecovery bool, skipProcesses bool) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) {
-	topologyRecovery, err = AttemptRecoveryRegistration(&analysisEntry, false, true)
-	if topologyRecovery == nil {
-		AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another fixMaster.", analysisEntry.AnalyzedInstanceKey))
-		return false, nil, err
-	}
-	log.Infof("Analysis: %v, will fix master to read-write %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceKey)
-
-	unlock, err := LockShard(analysisEntry.AnalyzedInstanceKey)
-	if err != nil {
-		log.Infof("CheckAndRecover: Analysis: %+v, InstanceKey: %+v, candidateInstanceKey: %+v, "+
-			"skipProcesses: %v: NOT detecting/recovering host, could not obtain shard lock (%v)",
-			analysisEntry.Analysis, analysisEntry.AnalyzedInstanceKey, candidateInstanceKey, skipProcesses, err)
-		return false, topologyRecovery, err
-	}
-	defer unlock(&err)
-
-	if err := TabletUndoDemoteMaster(analysisEntry.AnalyzedInstanceKey); err != nil {
-		return false, topologyRecovery, err
-	}
-	return true, topologyRecovery, nil
-}
-
-// fixReplica sets the replica as read-only and points it at the current master.
-func fixReplica(analysisEntry inst.ReplicationAnalysis, candidateInstanceKey *inst.InstanceKey, forceInstanceRecovery bool, skipProcesses bool) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) {
-	topologyRecovery, err = AttemptRecoveryRegistration(&analysisEntry, false, true)
-	if topologyRecovery == nil {
-		AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another fixReplica.", analysisEntry.AnalyzedInstanceKey))
-		return false, nil, err
-	}
-	log.Infof("Analysis: %v, will fix replica %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceKey)
-	if _, err := inst.SetReadOnly(&analysisEntry.AnalyzedInstanceKey, true); err != nil {
-		return false, topologyRecovery, err
-	}
-
-	masterKey, err := ShardMaster(&analysisEntry.AnalyzedInstanceKey)
-	if err != nil {
-		log.Info("Could not compute master for %+v", analysisEntry.AnalyzedInstanceKey)
-		return false, topologyRecovery, err
-	}
-	if _, err := inst.MoveBelowGTID(&analysisEntry.AnalyzedInstanceKey, masterKey); err != nil {
-		return false, topologyRecovery, err
-	}
-	return true, topologyRecovery, nil
-}
diff --git a/go/vt/orchestrator/ssl/ssl.go b/go/vt/orchestrator/ssl/ssl.go
index 325400b9ec..3f20a5ae61 100644
--- a/go/vt/orchestrator/ssl/ssl.go
+++ b/go/vt/orchestrator/ssl/ssl.go
@@ -75,7 +75,7 @@ func ReadCAFile(caFile string) (*x509.CertPool, error) {
 		if !caCertPool.AppendCertsFromPEM(data) {
 			return nil, errors.New("No certificates parsed")
 		}
-		log.Infof("Read in CA file: %v", caFile)
+		log.Info("Read in CA file:", caFile)
 	}
 	return caCertPool, nil
 }
@@ -166,7 +166,7 @@ func ReadPEMData(pemFile string, pemPass []byte) ([]byte, error) {
 		if err != nil {
 			return pemData, err
 		} else {
-			log.Infof("Decrypted %v successfully", pemFile)
+			log.Info("Decrypted", pemFile, "successfully")
 		}
 		// Shove the decrypted DER bytes into a new pem Block with blank headers
 		var newBlock pem.Block
diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go
index f3a52c2417..cd83cf4221 100644
--- a/go/vt/vtctl/vtctl.go
+++ b/go/vt/vtctl/vtctl.go
@@ -316,7 +316,7 @@ var commands = []commandGroup{
 				"Start a Resharding process. Example: Reshard -cells='zone1,alias1' -tablet_types='master,replica,rdonly'  ks.workflow001 '0' '-80,80-'"},
 			{"MoveTables", commandMoveTables,
 				"[-cells=<cells>] [-tablet_types=<source_tablet_types>] -workflow=<workflow> <source_keyspace> <target_keyspace> <table_specs>",
-				`Move table(s) to another keyspace, table_specs is a list of tables or the tables section of the vschema for the target keyspace. Example: '{"t1":{"column_vindexes": [{"column": "id1", "name": "hash"}]}, "t2":{"column_vindexes": [{"column": "id2", "name": "hash"}]}}'.  In the case of an unsharded target keyspace the vschema for each table may be empty. Example: '{"t1":{}, "t2":{}}'.`},
+				`Move table(s) to another keyspace, table_specs is a list of tables or the tables section of the vschema for the target keyspace. Example: '{"t1":{"column_vindexes": [{"column": "id1", "name": "hash"}]}, "t2":{"column_vindexes": [{"column": "id2", "name": "hash"}]}}'`},
 			{"DropSources", commandDropSources,
 				"[-dry_run] [-rename_tables] <keyspace.workflow>",
 				"After a MoveTables or Resharding workflow cleanup unused artifacts like source tables, source shards and blacklists"},
@@ -1891,9 +1891,9 @@ func commandReshard(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.F
 }
 
 func commandMoveTables(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error {
-	workflow := subFlags.String("workflow", "", "Workflow name. Can be any descriptive string. Will be used to later migrate traffic via SwitchReads/SwitchWrites.")
+	workflow := subFlags.String("workflow", "", "Workflow name. Will be used to later migrate traffic.")
 	cells := subFlags.String("cells", "", "Cell(s) or CellAlias(es) (comma-separated) to replicate from.")
-	tabletTypes := subFlags.String("tablet_types", "", "Source tablet types to replicate from (e.g. master, replica, rdonly). Defaults to -vreplication_tablet_type parameter value for the tablet, which has the default value of replica.")
+	tabletTypes := subFlags.String("tablet_types", "", "Source tablet types to replicate from.")
 	if err := subFlags.Parse(args); err != nil {
 		return err
 	}
diff --git a/go/vt/vtgate/engine/limit.go b/go/vt/vtgate/engine/limit.go
index e712c182dc..c43b6a4b28 100644
--- a/go/vt/vtgate/engine/limit.go
+++ b/go/vt/vtgate/engine/limit.go
@@ -94,14 +94,11 @@ func (l *Limit) StreamExecute(vcursor VCursor, bindVars map[string]*querypb.Bind
 	if err != nil {
 		return err
 	}
-	offset, err := l.fetchOffset(bindVars)
-	if err != nil {
-		return err
+	if !l.Offset.IsNull() {
+		return fmt.Errorf("offset not supported for stream execute queries")
 	}
 
-	// When offset is present, we hijack the limit value so we can calculate
-	// the offset in memory from the result of the scatter query with count + offset.
-	bindVars["__upper_limit"] = sqltypes.Int64BindVariable(int64(count + offset))
+	bindVars["__upper_limit"] = sqltypes.Int64BindVariable(int64(count))
 
 	err = l.Input.StreamExecute(vcursor, bindVars, wantfields, func(qr *sqltypes.Result) error {
 		if len(qr.Fields) != 0 {
@@ -109,31 +106,19 @@ func (l *Limit) StreamExecute(vcursor VCursor, bindVars map[string]*querypb.Bind
 				return err
 			}
 		}
-		inputSize := len(qr.Rows)
-		if inputSize == 0 {
+		if len(qr.Rows) == 0 {
 			return nil
 		}
 
-		// we've still not seen all rows we need to see before we can return anything to the client
-		if offset > 0 {
-			if inputSize <= offset {
-				// not enough to return anything yet
-				offset -= inputSize
-				return nil
-			}
-			qr.Rows = qr.Rows[offset:]
-			offset = 0
-		}
-
 		if count == 0 {
+			// Unreachable: this is just a failsafe.
 			return io.EOF
 		}
 
 		// reduce count till 0.
 		result := &sqltypes.Result{Rows: qr.Rows}
-		resultSize := len(result.Rows)
-		if count > resultSize {
-			count -= resultSize
+		if count > len(result.Rows) {
+			count -= len(result.Rows)
 			return callback(result)
 		}
 		result.Rows = result.Rows[:count]
@@ -155,7 +140,7 @@ func (l *Limit) StreamExecute(vcursor VCursor, bindVars map[string]*querypb.Bind
 	return nil
 }
 
-// GetFields implements the Primitive interface.
+// GetFields satisfies the Primtive interface.
 func (l *Limit) GetFields(vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) {
 	return l.Input.GetFields(vcursor, bindVars)
 }
@@ -165,16 +150,11 @@ func (l *Limit) Inputs() []Primitive {
 	return []Primitive{l.Input}
 }
 
-//NeedsTransaction implements the Primitive interface.
 func (l *Limit) NeedsTransaction() bool {
 	return l.Input.NeedsTransaction()
 }
 
 func (l *Limit) fetchCount(bindVars map[string]*querypb.BindVariable) (int, error) {
-	if l.Count.IsNull() {
-		return 0, nil
-	}
-
 	resolved, err := l.Count.ResolveValue(bindVars)
 	if err != nil {
 		return 0, err
diff --git a/go/vt/vtgate/planbuilder/limit.go b/go/vt/vtgate/planbuilder/limit.go
index 796850b3b1..74fdc75418 100644
--- a/go/vt/vtgate/planbuilder/limit.go
+++ b/go/vt/vtgate/planbuilder/limit.go
@@ -18,9 +18,11 @@ package planbuilder
 
 import (
 	"errors"
+	"fmt"
 
-	"vitess.io/vitess/go/vt/sqlparser"
 	"vitess.io/vitess/go/vt/vterrors"
+
+	"vitess.io/vitess/go/vt/sqlparser"
 	"vitess.io/vitess/go/vt/vtgate/engine"
 )
 
@@ -91,12 +93,17 @@ func (l *limit) SetLimit(limit *sqlparser.Limit) error {
 	}
 	l.elimit.Count = pv
 
-	if limit.Offset != nil {
-		pv, err = sqlparser.NewPlanValue(limit.Offset)
+	switch offset := limit.Offset.(type) {
+	case *sqlparser.Literal:
+		pv, err = sqlparser.NewPlanValue(offset)
 		if err != nil {
-			return vterrors.Wrap(err, "unexpected expression in OFFSET")
+			return err
 		}
 		l.elimit.Offset = pv
+	case nil:
+		// NOOP
+	default:
+		return fmt.Errorf("unexpected expression in LIMIT: %v", sqlparser.String(limit))
 	}
 
 	l.input.SetUpperLimit(sqlparser.NewArgument([]byte(":__upper_limit")))
diff --git a/go/vt/vtgate/planbuilder/select.go b/go/vt/vtgate/planbuilder/select.go
index 2a5f0c9793..66e6d3e8c9 100644
--- a/go/vt/vtgate/planbuilder/select.go
+++ b/go/vt/vtgate/planbuilder/select.go
@@ -146,7 +146,7 @@ func (pb *primitiveBuilder) processSelect(sel *sqlparser.Select, outer *symtab)
 }
 
 func handleDualSelects(sel *sqlparser.Select, vschema ContextVSchema) (engine.Primitive, error) {
-	if !isOnlyDual(sel.From) {
+	if !isOnlyDual(sel) {
 		return nil, nil
 	}
 
@@ -191,11 +191,16 @@ func buildLockingPrimitive(sel *sqlparser.Select, vschema ContextVSchema) (engin
 	}, nil
 }
 
-func isOnlyDual(from sqlparser.TableExprs) bool {
-	if len(from) > 1 {
+func isOnlyDual(sel *sqlparser.Select) bool {
+	if sel.Where != nil || sel.GroupBy != nil || sel.Having != nil || sel.Limit != nil || sel.OrderBy != nil {
+		// we can only deal with queries without any other subclauses - just SELECT and FROM, nothing else is allowed
 		return false
 	}
-	table, ok := from[0].(*sqlparser.AliasedTableExpr)
+
+	if len(sel.From) > 1 {
+		return false
+	}
+	table, ok := sel.From[0].(*sqlparser.AliasedTableExpr)
 	if !ok {
 		return false
 	}
diff --git a/go/vt/wrangler/vexec.go b/go/vt/wrangler/vexec.go
index f60415f070..72e8ab716a 100644
--- a/go/vt/wrangler/vexec.go
+++ b/go/vt/wrangler/vexec.go
@@ -493,18 +493,15 @@ func (wr *Wrangler) printWorkflowList(workflows []string) {
 
 func (wr *Wrangler) getCopyState(ctx context.Context, tablet *topo.TabletInfo, id int64) ([]copyState, error) {
 	var cs []copyState
-	query := fmt.Sprintf("select table_name, lastpk from _vt.copy_state where vrepl_id = %d", id)
+	query := fmt.Sprintf(`select table_name, lastpk from _vt.copy_state where vrepl_id = %d`, id)
 	qr, err := wr.VReplicationExec(ctx, tablet.Alias, query)
 	if err != nil {
 		return nil, err
 	}
-
-	result := sqltypes.Proto3ToResult(qr)
-	if result != nil {
-		for _, row := range result.Rows {
-			// These fields are varbinary, but close enough
-			table := row[0].ToString()
-			lastPK := row[1].ToString()
+	if qr != nil {
+		for _, row := range qr.Rows {
+			table := string(row.Values[0])
+			lastPK := string(row.Values[1])
 			copyState := copyState{
 				Table:  table,
 				LastPK: lastPK,


Test patch:
diff --git a/go/cmd/orchestrator/plugin_kubernetestopo.go b/go/cmd/orchestrator/plugin_kubernetestopo.go
deleted file mode 100644
index 671d0c8321..0000000000
--- a/go/cmd/orchestrator/plugin_kubernetestopo.go
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-Copyright 2020 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.
-*/
-
-package main
-
-// This plugin imports k8stopo to register the kubernetes implementation of TopoServer.
-
-import (
-	_ "vitess.io/vitess/go/vt/topo/k8stopo"
-)
diff --git a/go/test/endtoend/cluster/vttablet_process.go b/go/test/endtoend/cluster/vttablet_process.go
index b6335d9776..3a33455bed 100644
--- a/go/test/endtoend/cluster/vttablet_process.go
+++ b/go/test/endtoend/cluster/vttablet_process.go
@@ -370,7 +370,7 @@ func VttabletProcessInstance(port int, grpcPort int, tabletUID int, cell string,
 	vttablet := &VttabletProcess{
 		Name:                        "vttablet",
 		Binary:                      "vttablet",
-		FileToLogQueries:            path.Join(tmpDirectory, fmt.Sprintf("/vt_%010d_querylog.txt", tabletUID)),
+		FileToLogQueries:            path.Join(tmpDirectory, fmt.Sprintf("/vt_%010d/querylog.txt", tabletUID)),
 		Directory:                   path.Join(os.Getenv("VTDATAROOT"), fmt.Sprintf("/vt_%010d", tabletUID)),
 		TabletPath:                  fmt.Sprintf("%s-%010d", cell, tabletUID),
 		ServiceMap:                  "grpc-queryservice,grpc-tabletmanager,grpc-updatestream,grpc-throttler",
diff --git a/go/test/endtoend/vtgate/misc_test.go b/go/test/endtoend/vtgate/misc_test.go
index bf76b42092..6d5f159344 100644
--- a/go/test/endtoend/vtgate/misc_test.go
+++ b/go/test/endtoend/vtgate/misc_test.go
@@ -319,18 +319,6 @@ func TestInformationSchemaQuery(t *testing.T) {
 	assert.Equal(t, "vt_ks", qr.Rows[0][0].ToString())
 }
 
-func TestOffsetAndLimitWithOLAP(t *testing.T) {
-	ctx := context.Background()
-	conn, err := mysql.Connect(ctx, &vtParams)
-	require.NoError(t, err)
-	defer conn.Close()
-
-	exec(t, conn, "insert into t1(id1, id2) values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)")
-	assertMatches(t, conn, "select id1 from t1 order by id1 limit 3 offset 2", "[[INT64(3)] [INT64(4)] [INT64(5)]]")
-	exec(t, conn, "set workload='olap'")
-	assertMatches(t, conn, "select id1 from t1 order by id1 limit 3 offset 2", "[[INT64(3)] [INT64(4)] [INT64(5)]]")
-}
-
 func assertMatches(t *testing.T, conn *mysql.Conn, query, expected string) {
 	t.Helper()
 	qr := exec(t, conn, query)
diff --git a/go/vt/vtctld/api_test.go b/go/vt/vtctld/api_test.go
index de0575230b..ebf2880bc1 100644
--- a/go/vt/vtctld/api_test.go
+++ b/go/vt/vtctld/api_test.go
@@ -184,23 +184,22 @@ func TestAPI(t *testing.T) {
 	// Test cases.
 	table := []struct {
 		method, path, body, want string
-		statusCode               int
 	}{
 		// Create snapshot keyspace using API
 		{"POST", "vtctl/", `["CreateKeyspace", "-keyspace_type=SNAPSHOT", "-base_keyspace=ks1", "-snapshot_time=2006-01-02T15:04:05+00:00", "ks3"]`, `{
 		   "Error": "",
 		   "Output": ""
-		}`, http.StatusOK},
+		}`},
 
 		// Cells
-		{"GET", "cells", "", `["cell1","cell2"]`, http.StatusOK},
+		{"GET", "cells", "", `["cell1","cell2"]`},
 
 		// Keyspace
-		{"GET", "keyspace/doesnt-exist/tablets/", "", ``, http.StatusNotFound},
-		{"GET", "keyspace/ks1/tablets/", "", keyspaceKs1AllTablets, http.StatusOK},
-		{"GET", "keyspace/ks1/tablets/-80", "", keyspaceKs1AllTablets, http.StatusOK},
-		{"GET", "keyspace/ks1/tablets/80-", "", `[]`, http.StatusOK},
-		{"GET", "keyspace/ks1/tablets/?cells=cell1,cell2", "", keyspaceKs1AllTablets, http.StatusOK},
+		{"GET", "keyspace/doesnt-exist/tablets/", "", ``},
+		{"GET", "keyspace/ks1/tablets/", "", keyspaceKs1AllTablets},
+		{"GET", "keyspace/ks1/tablets/-80", "", keyspaceKs1AllTablets},
+		{"GET", "keyspace/ks1/tablets/80-", "", `[]`},
+		{"GET", "keyspace/ks1/tablets/?cells=cell1,cell2", "", keyspaceKs1AllTablets},
 		{"GET", "keyspace/ks1/tablets/?cells=cell1", "", `[
 			{
 				"alias": {
@@ -228,8 +227,8 @@ func TestAPI(t *testing.T) {
 				},
 				"url": "http://mysql1-cell1.test.net:100"
 			}
-		]`, http.StatusOK},
-		{"GET", "keyspace/ks1/tablets/?cells=cell3", "", `[]`, http.StatusOK},
+		]`},
+		{"GET", "keyspace/ks1/tablets/?cells=cell3", "", `[]`},
 		{"GET", "keyspace/ks1/tablets/?cell=cell2", "", `[
 			{
 				"alias": {
@@ -250,11 +249,11 @@ func TestAPI(t *testing.T) {
 				"mysql_port": 3306,
 				"url": "http://mysql2-cell2.test.net:200"
 			}
-		]`, http.StatusOK},
-		{"GET", "keyspace/ks1/tablets/?cell=cell3", "", `[]`, http.StatusOK},
+		]`},
+		{"GET", "keyspace/ks1/tablets/?cell=cell3", "", `[]`},
 
 		// Keyspaces
-		{"GET", "keyspaces", "", `["ks1", "ks3"]`, http.StatusOK},
+		{"GET", "keyspaces", "", `["ks1", "ks3"]`},
 		{"GET", "keyspaces/ks1", "", `{
 				"sharding_column_name": "shardcol",
 				"sharding_column_type": 0,
@@ -262,17 +261,17 @@ func TestAPI(t *testing.T) {
                                 "keyspace_type":0,
                                 "base_keyspace":"",
                                 "snapshot_time":null
-			}`, http.StatusOK},
-		{"GET", "keyspaces/nonexistent", "", "404 page not found", http.StatusNotFound},
+			}`},
+		{"GET", "keyspaces/nonexistent", "", "404 page not found"},
 		{"POST", "keyspaces/ks1?action=TestKeyspaceAction", "", `{
 				"Name": "TestKeyspaceAction",
 				"Parameters": "ks1",
 				"Output": "TestKeyspaceAction Result",
 				"Error": false
-			}`, http.StatusOK},
+			}`},
 
 		// Shards
-		{"GET", "shards/ks1/", "", `["-80","80-"]`, http.StatusOK},
+		{"GET", "shards/ks1/", "", `["-80","80-"]`},
 		{"GET", "shards/ks1/-80", "", `{
 				"master_alias": null,
 				"master_term_start_time":null,
@@ -284,27 +283,27 @@ func TestAPI(t *testing.T) {
 				"source_shards": [],
 				"tablet_controls": [],
 				"is_master_serving": true
-			}`, http.StatusOK},
-		{"GET", "shards/ks1/-DEAD", "", "404 page not found", http.StatusNotFound},
+			}`},
+		{"GET", "shards/ks1/-DEAD", "", "404 page not found"},
 		{"POST", "shards/ks1/-80?action=TestShardAction", "", `{
 				"Name": "TestShardAction",
 				"Parameters": "ks1/-80",
 				"Output": "TestShardAction Result",
 				"Error": false
-			}`, http.StatusOK},
+			}`},
 
 		// Tablets
 		{"GET", "tablets/?shard=ks1%2F-80", "", `[
 				{"cell":"cell1","uid":100},
 				{"cell":"cell2","uid":200}
-			]`, http.StatusOK},
+			]`},
 		{"GET", "tablets/?cell=cell1", "", `[
 				{"cell":"cell1","uid":100}
-			]`, http.StatusOK},
+			]`},
 		{"GET", "tablets/?shard=ks1%2F-80&cell=cell2", "", `[
 				{"cell":"cell2","uid":200}
-			]`, http.StatusOK},
-		{"GET", "tablets/?shard=ks1%2F80-&cell=cell1", "", `[]`, http.StatusOK},
+			]`},
+		{"GET", "tablets/?shard=ks1%2F80-&cell=cell1", "", `[]`},
 		{"GET", "tablets/cell1-100", "", `{
 				"alias": {"cell": "cell1", "uid": 100},
 				"hostname": "mysql1-cell1.test.net",
@@ -318,14 +317,14 @@ func TestAPI(t *testing.T) {
 				"mysql_hostname": "mysql1-cell1.test.net",
 				"mysql_port": 3306,
 				"url":"http://mysql1-cell1.test.net:100"
-			}`, http.StatusOK},
-		{"GET", "tablets/nonexistent-999", "", "404 page not found", http.StatusNotFound},
+			}`},
+		{"GET", "tablets/nonexistent-999", "", "404 page not found"},
 		{"POST", "tablets/cell1-100?action=TestTabletAction", "", `{
 				"Name": "TestTabletAction",
 				"Parameters": "cell1-0000000100",
 				"Output": "TestTabletAction Result",
 				"Error": false
-			}`, http.StatusOK},
+			}`},
 
 		// Tablet Updates
 		{"GET", "tablet_statuses/?keyspace=ks1&cell=cell1&type=REPLICA&metric=lag", "", `[
@@ -337,7 +336,7 @@ func TestAPI(t *testing.T) {
 		    "ShardLabels": ["-80", "80-"],
 		    "YGridLines": [0.5]
 		  }
-		]`, http.StatusOK},
+		]`},
 		{"GET", "tablet_statuses/?keyspace=ks1&cell=all&type=all&metric=lag", "", `[
 		{
 		  "Data":[[-1,400],[-1,300],[200,-1],[100,-1]],
@@ -349,7 +348,7 @@ func TestAPI(t *testing.T) {
 		  "ShardLabels":["-80","80-"],
 		  "YGridLines":[0.5,1.5,2.5,3.5]
 		}
-		]`, http.StatusOK},
+		]`},
 		{"GET", "tablet_statuses/?keyspace=all&cell=all&type=all&metric=lag", "", `[
 		  {
 		   "Data":[[-1,300],[200,-1]],
@@ -371,47 +370,47 @@ func TestAPI(t *testing.T) {
 		  "ShardLabels":["0"],
 		  "YGridLines":[0.5, 1.5]
 		  }
-		]`, http.StatusOK},
-		{"GET", "tablet_statuses/cell1/REPLICA/lag", "", "can't get tablet_statuses: invalid target path: \"cell1/REPLICA/lag\"  expected path: ?keyspace=<keyspace>&cell=<cell>&type=<type>&metric=<metric>", http.StatusInternalServerError},
-		{"GET", "tablet_statuses/?keyspace=ks1&cell=cell1&type=hello&metric=lag", "", "can't get tablet_statuses: invalid tablet type: unknown TabletType hello", http.StatusInternalServerError},
+		]`},
+		{"GET", "tablet_statuses/cell1/REPLICA/lag", "", "can't get tablet_statuses: invalid target path: \"cell1/REPLICA/lag\"  expected path: ?keyspace=<keyspace>&cell=<cell>&type=<type>&metric=<metric>"},
+		{"GET", "tablet_statuses/?keyspace=ks1&cell=cell1&type=hello&metric=lag", "", "can't get tablet_statuses: invalid tablet type: unknown TabletType hello"},
 
 		// Tablet Health
 		{"GET", "tablet_health/cell1/100", "", `{ "Key": "", "Tablet": { "alias": { "cell": "cell1", "uid": 100 },"port_map": { "vt": 100 }, "keyspace": "ks1", "shard": "-80", "type": 2},
 		  "Name": "", "Target": { "keyspace": "ks1", "shard": "-80", "tablet_type": 2 }, "Up": true, "Serving": true, "TabletExternallyReparentedTimestamp": 0,
-		  "Stats": { "seconds_behind_master": 100 }, "LastError": null }`, http.StatusOK},
-		{"GET", "tablet_health/cell1", "", "can't get tablet_health: invalid tablet_health path: \"cell1\"  expected path: /tablet_health/<cell>/<uid>", http.StatusInternalServerError},
-		{"GET", "tablet_health/cell1/gh", "", "can't get tablet_health: incorrect uid", http.StatusInternalServerError},
+		  "Stats": { "seconds_behind_master": 100 }, "LastError": null }`},
+		{"GET", "tablet_health/cell1", "", "can't get tablet_health: invalid tablet_health path: \"cell1\"  expected path: /tablet_health/<cell>/<uid>"},
+		{"GET", "tablet_health/cell1/gh", "", "can't get tablet_health: incorrect uid"},
 
 		// Topology Info
 		{"GET", "topology_info/?keyspace=all&cell=all", "", `{
 		   "Keyspaces": ["ks1", "ks2"],
 		   "Cells": ["cell1","cell2"],
 		   "TabletTypes": ["REPLICA","RDONLY"]
-		}`, http.StatusOK},
+		}`},
 		{"GET", "topology_info/?keyspace=ks1&cell=cell1", "", `{
 		   "Keyspaces": ["ks1", "ks2"],
 		   "Cells": ["cell1","cell2"],
 		   "TabletTypes": ["REPLICA", "RDONLY"]
-		}`, http.StatusOK},
+		}`},
 
 		// vtctl RunCommand
 		{"POST", "vtctl/", `["GetKeyspace","ks1"]`, `{
 		   "Error": "",
 		   "Output": "{\n  \"sharding_column_name\": \"shardcol\",\n  \"sharding_column_type\": 0,\n  \"served_froms\": [\n  ],\n  \"keyspace_type\": 0,\n  \"base_keyspace\": \"\",\n  \"snapshot_time\": null\n}\n\n"
-		}`, http.StatusOK},
+		}`},
 		{"POST", "vtctl/", `["GetKeyspace","ks3"]`, `{
 		   "Error": "",
 		   "Output": "{\n  \"sharding_column_name\": \"\",\n  \"sharding_column_type\": 0,\n  \"served_froms\": [\n  ],\n  \"keyspace_type\": 1,\n  \"base_keyspace\": \"ks1\",\n  \"snapshot_time\": {\n    \"seconds\": \"1136214245\",\n    \"nanoseconds\": 0\n  }\n}\n\n"
-		}`, http.StatusOK},
+		}`},
 		{"POST", "vtctl/", `["GetVSchema","ks3"]`, `{
 		   "Error": "",
 		   "Output": "{\n  \"sharded\": true,\n  \"vindexes\": {\n    \"name1\": {\n      \"type\": \"hash\"\n    }\n  },\n  \"tables\": {\n    \"table1\": {\n      \"columnVindexes\": [\n        {\n          \"column\": \"column1\",\n          \"name\": \"name1\"\n        }\n      ]\n    }\n  },\n  \"requireExplicitRouting\": true\n}\n\n"
-		}`, http.StatusOK},
+		}`},
 		{"POST", "vtctl/", `["GetKeyspace","does_not_exist"]`, `{
 			"Error": "node doesn't exist: keyspaces/does_not_exist/Keyspace",
 		   "Output": ""
-		}`, http.StatusOK},
-		{"POST", "vtctl/", `["Panic"]`, `uncaught panic: this command panics on purpose`, http.StatusInternalServerError},
+		}`},
+		{"POST", "vtctl/", `["Panic"]`, `uncaught panic: this command panics on purpose`},
 	}
 	for _, in := range table {
 		t.Run(in.method+in.path, func(t *testing.T) {
@@ -441,10 +440,6 @@ func TestAPI(t *testing.T) {
 				return
 			}
 
-			if resp.StatusCode != in.statusCode {
-				t.Fatalf("[%v] got unexpected status code %d, want %d", in.path, resp.StatusCode, in.statusCode)
-			}
-
 			got := compactJSON(body)
 			want := compactJSON([]byte(in.want))
 			if want == "" {
diff --git a/go/vt/vtgate/engine/limit_test.go b/go/vt/vtgate/engine/limit_test.go
index d7eb5077e7..e0dd4ddada 100644
--- a/go/vt/vtgate/engine/limit_test.go
+++ b/go/vt/vtgate/engine/limit_test.go
@@ -432,49 +432,6 @@ func TestLimitStreamExecute(t *testing.T) {
 	}
 }
 
-func TestOffsetStreamExecute(t *testing.T) {
-	bindVars := make(map[string]*querypb.BindVariable)
-	fields := sqltypes.MakeTestFields(
-		"col1|col2",
-		"int64|varchar",
-	)
-	inputResult := sqltypes.MakeTestResult(
-		fields,
-		"a|1",
-		"b|2",
-		"c|3",
-		"d|4",
-		"e|5",
-		"f|6",
-	)
-	fp := &fakePrimitive{
-		results: []*sqltypes.Result{inputResult},
-	}
-
-	l := &Limit{
-		Offset: int64PlanValue(2),
-		Count:  int64PlanValue(3),
-		Input:  fp,
-	}
-
-	var results []*sqltypes.Result
-	err := l.StreamExecute(nil, bindVars, false, func(qr *sqltypes.Result) error {
-		results = append(results, qr)
-		return nil
-	})
-	require.NoError(t, err)
-	wantResults := sqltypes.MakeTestStreamingResults(
-		fields,
-		"c|3",
-		"d|4",
-		"---",
-		"e|5",
-	)
-	if !reflect.DeepEqual(results, wantResults) {
-		t.Errorf("l.StreamExecute:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults))
-	}
-}
-
 func TestLimitGetFields(t *testing.T) {
 	result := sqltypes.MakeTestResult(
 		sqltypes.MakeTestFields(
diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go
index a0ffb4533e..cbdb136275 100644
--- a/go/vt/vtgate/executor_select_test.go
+++ b/go/vt/vtgate/executor_select_test.go
@@ -221,78 +221,6 @@ func TestStreamBuffering(t *testing.T) {
 	}
 }
 
-func TestStreamLimitOffset(t *testing.T) {
-	executor, sbc1, sbc2, _ := createLegacyExecutorEnv()
-
-	// This test is similar to TestStreamUnsharded except that it returns a Result > 10 bytes,
-	// such that the splitting of the Result into multiple Result responses gets tested.
-	sbc1.SetResults([]*sqltypes.Result{{
-		Fields: []*querypb.Field{
-			{Name: "id", Type: sqltypes.Int32},
-			{Name: "textcol", Type: sqltypes.VarChar},
-		},
-		Rows: [][]sqltypes.Value{{
-			sqltypes.NewInt32(1),
-			sqltypes.NewVarChar("1234"),
-		}, {
-			sqltypes.NewInt32(4),
-			sqltypes.NewVarChar("4567"),
-		}},
-	}})
-
-	sbc2.SetResults([]*sqltypes.Result{{
-		Fields: []*querypb.Field{
-			{Name: "id", Type: sqltypes.Int32},
-			{Name: "textcol", Type: sqltypes.VarChar},
-		},
-		Rows: [][]sqltypes.Value{{
-			sqltypes.NewInt32(2),
-			sqltypes.NewVarChar("2345"),
-		}},
-	}})
-
-	results := make(chan *sqltypes.Result, 10)
-	err := executor.StreamExecute(
-		context.Background(),
-		"TestStreamLimitOffset",
-		NewSafeSession(masterSession),
-		"select id, textcol from user order by id limit 2 offset 2",
-		nil,
-		querypb.Target{
-			TabletType: topodatapb.TabletType_MASTER,
-		},
-		func(qr *sqltypes.Result) error {
-			results <- qr
-			return nil
-		},
-	)
-	close(results)
-	require.NoError(t, err)
-	wantResult := &sqltypes.Result{
-		Fields: []*querypb.Field{
-			{Name: "id", Type: sqltypes.Int32},
-			{Name: "textcol", Type: sqltypes.VarChar},
-		},
-
-		Rows: [][]sqltypes.Value{{
-			sqltypes.NewInt32(1),
-			sqltypes.NewVarChar("1234"),
-		}, {
-			sqltypes.NewInt32(1),
-			sqltypes.NewVarChar("foo"),
-		}},
-	}
-	var gotResults []*sqltypes.Result
-	for r := range results {
-		gotResults = append(gotResults, r)
-	}
-	res := gotResults[0]
-	for i := 1; i < len(gotResults); i++ {
-		res.Rows = append(res.Rows, gotResults[i].Rows...)
-	}
-	utils.MustMatch(t, wantResult, res, "")
-}
-
 func TestSelectLastInsertId(t *testing.T) {
 	masterSession.LastInsertId = 52
 	executor, _, _, _ := createLegacyExecutorEnv()
diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.txt b/go/vt/vtgate/planbuilder/testdata/select_cases.txt
index 17aa01ebe0..35750f6e37 100644
--- a/go/vt/vtgate/planbuilder/testdata/select_cases.txt
+++ b/go/vt/vtgate/planbuilder/testdata/select_cases.txt
@@ -1349,6 +1349,24 @@
   }
 }
 
+# don't filter on the vtgate
+"select 42 from dual where false"
+{
+  "QueryType": "SELECT",
+  "Original": "select 42 from dual where false",
+  "Instructions": {
+    "OperatorType": "Route",
+    "Variant": "SelectReference",
+    "Keyspace": {
+      "Name": "main",
+      "Sharded": false
+    },
+    "FieldQuery": "select 42 from dual where 1 != 1",
+    "Query": "select 42 from dual where false",
+    "Table": "dual"
+  }
+}
+
 # testing SingleRow Projection with arithmetics
 "select 42+2"
 {
diff --git a/go/vt/wrangler/vexec_test.go b/go/vt/wrangler/vexec_test.go
index f816498fdb..415158041c 100644
--- a/go/vt/wrangler/vexec_test.go
+++ b/go/vt/wrangler/vexec_test.go
@@ -236,8 +236,8 @@ func TestWorkflowListStreams(t *testing.T) {
 					"Message": "",
 					"CopyState": [
 						{
-							"Table": "t1",
-							"LastPK": "pk1"
+							"Table": "t",
+							"LastPK": "1"
 						}
 					]
 				}
@@ -272,8 +272,8 @@ func TestWorkflowListStreams(t *testing.T) {
 					"Message": "",
 					"CopyState": [
 						{
-							"Table": "t1",
-							"LastPK": "pk1"
+							"Table": "t",
+							"LastPK": "1"
 						}
 					]
 				}