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  }