vitess.io/vitess@v0.16.2/go/vt/vttablet/tabletmanager/rpc_actions.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 tabletmanager
    18  
    19  import (
    20  	"fmt"
    21  	"time"
    22  
    23  	"vitess.io/vitess/go/vt/vterrors"
    24  
    25  	"context"
    26  
    27  	"vitess.io/vitess/go/vt/hook"
    28  	"vitess.io/vitess/go/vt/mysqlctl"
    29  	"vitess.io/vitess/go/vt/topotools"
    30  
    31  	tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata"
    32  	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
    33  )
    34  
    35  // DBAction is used to tell ChangeTabletType whether to call SetReadOnly on change to
    36  // PRIMARY tablet type
    37  type DBAction int
    38  
    39  // Allowed values for DBAction
    40  const (
    41  	DBActionNone = DBAction(iota)
    42  	DBActionSetReadWrite
    43  )
    44  
    45  // SemiSyncAction is used to tell fixSemiSync whether to change the semi-sync
    46  // settings or not.
    47  type SemiSyncAction int
    48  
    49  // Allowed values for SemiSyncAction
    50  const (
    51  	SemiSyncActionNone = SemiSyncAction(iota)
    52  	SemiSyncActionSet
    53  	SemiSyncActionUnset
    54  )
    55  
    56  // This file contains the implementations of RPCTM methods.
    57  // Major groups of methods are broken out into files named "rpc_*.go".
    58  
    59  // Ping makes sure RPCs work, and refreshes the tablet record.
    60  func (tm *TabletManager) Ping(ctx context.Context, args string) string {
    61  	return args
    62  }
    63  
    64  // GetPermissions returns the db permissions.
    65  func (tm *TabletManager) GetPermissions(ctx context.Context) (*tabletmanagerdatapb.Permissions, error) {
    66  	return mysqlctl.GetPermissions(tm.MysqlDaemon)
    67  }
    68  
    69  // SetReadOnly makes the mysql instance read-only or read-write.
    70  func (tm *TabletManager) SetReadOnly(ctx context.Context, rdonly bool) error {
    71  	if err := tm.lock(ctx); err != nil {
    72  		return err
    73  	}
    74  	defer tm.unlock()
    75  
    76  	return tm.MysqlDaemon.SetReadOnly(rdonly)
    77  }
    78  
    79  // ChangeType changes the tablet type
    80  func (tm *TabletManager) ChangeType(ctx context.Context, tabletType topodatapb.TabletType, semiSync bool) error {
    81  	if err := tm.lock(ctx); err != nil {
    82  		return err
    83  	}
    84  	defer tm.unlock()
    85  	return tm.changeTypeLocked(ctx, tabletType, DBActionNone, convertBoolToSemiSyncAction(semiSync))
    86  }
    87  
    88  // ChangeType changes the tablet type
    89  func (tm *TabletManager) changeTypeLocked(ctx context.Context, tabletType topodatapb.TabletType, action DBAction, semiSync SemiSyncAction) error {
    90  	// We don't want to allow multiple callers to claim a tablet as drained.
    91  	if tabletType == topodatapb.TabletType_DRAINED && tm.Tablet().Type == topodatapb.TabletType_DRAINED {
    92  		return fmt.Errorf("Tablet: %v, is already drained", tm.tabletAlias)
    93  	}
    94  
    95  	if err := tm.tmState.ChangeTabletType(ctx, tabletType, action); err != nil {
    96  		return err
    97  	}
    98  
    99  	// Let's see if we need to fix semi-sync acking.
   100  	if err := tm.fixSemiSyncAndReplication(tm.Tablet().Type, semiSync); err != nil {
   101  		return vterrors.Wrap(err, "fixSemiSyncAndReplication failed, may not ack correctly")
   102  	}
   103  	return nil
   104  }
   105  
   106  // Sleep sleeps for the duration
   107  func (tm *TabletManager) Sleep(ctx context.Context, duration time.Duration) {
   108  	if err := tm.lock(ctx); err != nil {
   109  		// client gave up
   110  		return
   111  	}
   112  	defer tm.unlock()
   113  
   114  	time.Sleep(duration)
   115  }
   116  
   117  // ExecuteHook executes the provided hook locally, and returns the result.
   118  func (tm *TabletManager) ExecuteHook(ctx context.Context, hk *hook.Hook) *hook.HookResult {
   119  	if err := tm.lock(ctx); err != nil {
   120  		// client gave up
   121  		return &hook.HookResult{}
   122  	}
   123  	defer tm.unlock()
   124  
   125  	// Execute the hooks
   126  	topotools.ConfigureTabletHook(hk, tm.tabletAlias)
   127  	return hk.Execute()
   128  }
   129  
   130  // RefreshState reload the tablet record from the topo server.
   131  func (tm *TabletManager) RefreshState(ctx context.Context) error {
   132  	if err := tm.lock(ctx); err != nil {
   133  		return err
   134  	}
   135  	defer tm.unlock()
   136  
   137  	return tm.tmState.RefreshFromTopo(ctx)
   138  }
   139  
   140  // RunHealthCheck will manually run the health check on the tablet.
   141  func (tm *TabletManager) RunHealthCheck(ctx context.Context) {
   142  	tm.QueryServiceControl.BroadcastHealth()
   143  }
   144  
   145  func convertBoolToSemiSyncAction(semiSync bool) SemiSyncAction {
   146  	if semiSync {
   147  		return SemiSyncActionSet
   148  	}
   149  	return SemiSyncActionUnset
   150  }