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 }