vitess.io/vitess@v0.16.2/go/vt/vttablet/tmclient/rpc_client_api.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package tmclient 18 19 import ( 20 "context" 21 "time" 22 23 "github.com/spf13/pflag" 24 25 "vitess.io/vitess/go/vt/hook" 26 "vitess.io/vitess/go/vt/log" 27 "vitess.io/vitess/go/vt/logutil" 28 "vitess.io/vitess/go/vt/mysqlctl/tmutils" 29 "vitess.io/vitess/go/vt/servenv" 30 31 querypb "vitess.io/vitess/go/vt/proto/query" 32 replicationdatapb "vitess.io/vitess/go/vt/proto/replicationdata" 33 tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" 34 topodatapb "vitess.io/vitess/go/vt/proto/topodata" 35 ) 36 37 // tabletManagerProtocol is the implementation to use for tablet 38 // manager protocol. 39 var tabletManagerProtocol = "grpc" 40 41 // RegisterFlags registers the tabletconn flags on a given flagset. It is 42 // exported for tests that need to inject a particular TabletManagerProtocol. 43 func RegisterFlags(fs *pflag.FlagSet) { 44 fs.StringVar(&tabletManagerProtocol, "tablet_manager_protocol", tabletManagerProtocol, "Protocol to use to make tabletmanager RPCs to vttablets.") 45 } 46 47 func init() { 48 for _, cmd := range []string{ 49 "vtbackup", 50 "vtcombo", 51 "vtctl", 52 "vtctld", 53 "vtctldclient", 54 "vtgr", 55 "vtorc", 56 "vttablet", 57 "vttestserver", 58 } { 59 servenv.OnParseFor(cmd, RegisterFlags) 60 } 61 } 62 63 // TabletManagerClient defines the interface used to talk to a remote tablet 64 type TabletManagerClient interface { 65 // 66 // Various read-only methods 67 // 68 69 // Ping will try to ping the remote tablet 70 Ping(ctx context.Context, tablet *topodatapb.Tablet) error 71 72 // GetSchema asks the remote tablet for its database schema 73 GetSchema(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.GetSchemaRequest) (*tabletmanagerdatapb.SchemaDefinition, error) 74 75 // GetPermissions asks the remote tablet for its permissions list 76 GetPermissions(ctx context.Context, tablet *topodatapb.Tablet) (*tabletmanagerdatapb.Permissions, error) 77 78 // 79 // Various read-write methods 80 // 81 82 // SetReadOnly makes the mysql instance read-only 83 SetReadOnly(ctx context.Context, tablet *topodatapb.Tablet) error 84 85 // SetReadWrite makes the mysql instance read-write 86 SetReadWrite(ctx context.Context, tablet *topodatapb.Tablet) error 87 88 // ChangeType asks the remote tablet to change its type 89 ChangeType(ctx context.Context, tablet *topodatapb.Tablet, dbType topodatapb.TabletType, semiSync bool) error 90 91 // Sleep will sleep for a duration (used for tests) 92 Sleep(ctx context.Context, tablet *topodatapb.Tablet, duration time.Duration) error 93 94 // ExecuteHook executes the provided hook remotely 95 ExecuteHook(ctx context.Context, tablet *topodatapb.Tablet, hk *hook.Hook) (*hook.HookResult, error) 96 97 // RefreshState asks the remote tablet to reload its tablet record 98 RefreshState(ctx context.Context, tablet *topodatapb.Tablet) error 99 100 // RunHealthCheck asks the remote tablet to run a health check cycle 101 RunHealthCheck(ctx context.Context, tablet *topodatapb.Tablet) error 102 103 // ReloadSchema asks the remote tablet to reload its schema 104 ReloadSchema(ctx context.Context, tablet *topodatapb.Tablet, waitPosition string) error 105 106 // PreflightSchema will test a list of schema changes. 107 PreflightSchema(ctx context.Context, tablet *topodatapb.Tablet, changes []string) ([]*tabletmanagerdatapb.SchemaChangeResult, error) 108 109 // ApplySchema will apply a schema change 110 ApplySchema(ctx context.Context, tablet *topodatapb.Tablet, change *tmutils.SchemaChange) (*tabletmanagerdatapb.SchemaChangeResult, error) 111 112 LockTables(ctx context.Context, tablet *topodatapb.Tablet) error 113 114 UnlockTables(ctx context.Context, tablet *topodatapb.Tablet) error 115 116 // ExecuteQuery executes a query remotely on the tablet. 117 // req.DbName is ignored in favor of using the tablet's DbName field, and, 118 // if req.CallerId is nil, the effective callerid will be extracted from 119 // the context. 120 ExecuteQuery(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.ExecuteQueryRequest) (*querypb.QueryResult, error) 121 122 // ExecuteFetchAsDba executes a query remotely using the DBA pool. 123 // req.DbName is ignored in favor of using the tablet's DbName field. 124 // If usePool is set, a connection pool may be used to make the 125 // query faster. Close() should close the pool in that case. 126 ExecuteFetchAsDba(ctx context.Context, tablet *topodatapb.Tablet, usePool bool, req *tabletmanagerdatapb.ExecuteFetchAsDbaRequest) (*querypb.QueryResult, error) 127 128 // ExecuteFetchAsAllPrivs executes a query remotely using the allprivs user. 129 // req.DbName is ignored in favor of using the tablet's DbName field. 130 ExecuteFetchAsAllPrivs(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.ExecuteFetchAsAllPrivsRequest) (*querypb.QueryResult, error) 131 132 // ExecuteFetchAsApp executes a query remotely using the App pool 133 // If usePool is set, a connection pool may be used to make the 134 // query faster. Close() should close the pool in that case. 135 ExecuteFetchAsApp(ctx context.Context, tablet *topodatapb.Tablet, usePool bool, req *tabletmanagerdatapb.ExecuteFetchAsAppRequest) (*querypb.QueryResult, error) 136 137 // 138 // Replication related methods 139 // 140 141 // PrimaryStatus returns the tablet's mysql primary status. 142 PrimaryStatus(ctx context.Context, tablet *topodatapb.Tablet) (*replicationdatapb.PrimaryStatus, error) 143 144 // ReplicationStatus returns the tablet's mysql replication status. 145 ReplicationStatus(ctx context.Context, tablet *topodatapb.Tablet) (*replicationdatapb.Status, error) 146 147 // FullStatus returns the tablet's mysql replication status. 148 FullStatus(ctx context.Context, tablet *topodatapb.Tablet) (*replicationdatapb.FullStatus, error) 149 150 // StopReplication stops the mysql replication 151 StopReplication(ctx context.Context, tablet *topodatapb.Tablet) error 152 153 // StopReplicationMinimum stops the mysql replication after it reaches 154 // the provided minimum point 155 StopReplicationMinimum(ctx context.Context, tablet *topodatapb.Tablet, stopPos string, waitTime time.Duration) (string, error) 156 157 // StartReplication starts the mysql replication 158 StartReplication(ctx context.Context, tablet *topodatapb.Tablet, semiSync bool) error 159 160 // StartReplicationUntilAfter starts replication until after the position specified 161 StartReplicationUntilAfter(ctx context.Context, tablet *topodatapb.Tablet, position string, duration time.Duration) error 162 163 // GetReplicas returns the addresses of the replicas 164 GetReplicas(ctx context.Context, tablet *topodatapb.Tablet) ([]string, error) 165 166 // PrimaryPosition returns the tablet's primary position 167 PrimaryPosition(ctx context.Context, tablet *topodatapb.Tablet) (string, error) 168 169 // WaitForPosition waits for the position to be reached 170 WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, pos string) error 171 172 // VExec executes a generic VExec command 173 VExec(ctx context.Context, tablet *topodatapb.Tablet, query, workflow, keyspace string) (*querypb.QueryResult, error) 174 175 // VReplicationExec executes a VReplication command 176 VReplicationExec(ctx context.Context, tablet *topodatapb.Tablet, query string) (*querypb.QueryResult, error) 177 VReplicationWaitForPos(ctx context.Context, tablet *topodatapb.Tablet, id int, pos string) error 178 179 VDiff(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.VDiffRequest) (*tabletmanagerdatapb.VDiffResponse, error) 180 181 // 182 // Reparenting related functions 183 // 184 185 // ResetReplication tells a tablet to completely reset its 186 // replication. All binary and relay logs are flushed. All 187 // replication positions are reset. 188 ResetReplication(ctx context.Context, tablet *topodatapb.Tablet) error 189 190 // InitPrimary tells a tablet to make itself the new primary, 191 // and return the replication position the replicas should use to 192 // reparent to it. 193 InitPrimary(ctx context.Context, tablet *topodatapb.Tablet, semiSync bool) (string, error) 194 195 // PopulateReparentJournal asks the primary to insert a row in 196 // its reparent_journal table. 197 PopulateReparentJournal(ctx context.Context, tablet *topodatapb.Tablet, timeCreatedNS int64, actionName string, tabletAlias *topodatapb.TabletAlias, pos string) error 198 199 // InitReplica tells a tablet to start replicating from the 200 // passed in primary tablet alias, and wait for the row in the 201 // reparent_journal table. 202 InitReplica(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias, replicationPosition string, timeCreatedNS int64, semiSync bool) error 203 204 // DemotePrimary tells the soon-to-be-former primary it's going to change, 205 // and it should go read-only and return its current position. 206 DemotePrimary(ctx context.Context, tablet *topodatapb.Tablet) (*replicationdatapb.PrimaryStatus, error) 207 208 // UndoDemotePrimary reverts all changes made by DemotePrimary 209 // To be used if we are unable to promote the chosen new primary 210 UndoDemotePrimary(ctx context.Context, tablet *topodatapb.Tablet, semiSync bool) error 211 212 // ReplicaWasPromoted tells the remote tablet it is now the primary 213 ReplicaWasPromoted(ctx context.Context, tablet *topodatapb.Tablet) error 214 215 // ResetReplicationParameters resets the replica replication parameters 216 ResetReplicationParameters(ctx context.Context, tablet *topodatapb.Tablet) error 217 218 // SetReplicationSource tells a tablet to start replicating from the 219 // passed in tablet alias, and wait for the row in the 220 // reparent_journal table (if timeCreatedNS is non-zero). 221 SetReplicationSource(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias, timeCreatedNS int64, waitPosition string, forceStartReplication bool, semiSync bool) error 222 223 // ReplicaWasRestarted tells the replica tablet its primary has changed 224 ReplicaWasRestarted(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias) error 225 226 // StopReplicationAndGetStatus stops replication and returns the 227 // current position. 228 StopReplicationAndGetStatus(ctx context.Context, tablet *topodatapb.Tablet, stopReplicationMode replicationdatapb.StopReplicationMode) (*replicationdatapb.StopReplicationStatus, error) 229 230 // PromoteReplica makes the tablet the new primary 231 PromoteReplica(ctx context.Context, tablet *topodatapb.Tablet, semiSync bool) (string, error) 232 233 // 234 // Backup / restore related methods 235 // 236 237 // Backup creates a database backup 238 Backup(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.BackupRequest) (logutil.EventStream, error) 239 240 // RestoreFromBackup deletes local data and restores database from backup 241 RestoreFromBackup(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.RestoreFromBackupRequest) (logutil.EventStream, error) 242 243 // 244 // Management methods 245 // 246 247 // Close will be called when this TabletManagerClient won't be 248 // used any more. It can be used to free any resource. 249 Close() 250 } 251 252 // TabletManagerClientFactory is the factory method to create 253 // TabletManagerClient objects. 254 type TabletManagerClientFactory func() TabletManagerClient 255 256 var tabletManagerClientFactories = make(map[string]TabletManagerClientFactory) 257 258 // RegisterTabletManagerClientFactory allows modules to register 259 // TabletManagerClient implementations. Should be called on init(). 260 func RegisterTabletManagerClientFactory(name string, factory TabletManagerClientFactory) { 261 if _, ok := tabletManagerClientFactories[name]; ok { 262 log.Fatalf("RegisterTabletManagerClient %s already exists", name) 263 } 264 tabletManagerClientFactories[name] = factory 265 } 266 267 // NewTabletManagerClient creates a new TabletManagerClient. Should be 268 // called after flags are parsed. 269 func NewTabletManagerClient() TabletManagerClient { 270 f, ok := tabletManagerClientFactories[tabletManagerProtocol] 271 if !ok { 272 log.Exitf("No TabletManagerProtocol registered with name %s", tabletManagerProtocol) 273 } 274 275 return f() 276 }