github.com/dolthub/go-mysql-server@v0.18.0/sql/binlogreplication/binlog_replication.go (about)

     1  // Copyright 2022 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package binlogreplication
    16  
    17  import (
    18  	"fmt"
    19  	"strconv"
    20  	"strings"
    21  	"time"
    22  
    23  	"github.com/dolthub/go-mysql-server/sql"
    24  )
    25  
    26  // BinlogReplicaController allows callers to control a binlog replica. Providers built on go-mysql-server may optionally
    27  // implement this interface and use it when constructing a SQL engine in order to receive callbacks when replication
    28  // statements (e.g. START REPLICA, SHOW REPLICA STATUS) are being handled.
    29  type BinlogReplicaController interface {
    30  	// StartReplica tells the binlog replica controller to start up replication processes for the current replication
    31  	// configuration. An error is returned if replication was unable to be started. Note the error response only signals
    32  	// whether there was a problem with the initial replication start up. Replication could fail after being started up
    33  	// successfully with no error response returned.
    34  	StartReplica(ctx *sql.Context) error
    35  
    36  	// StopReplica tells the binlog replica controller to stop all replication processes. An error is returned if there
    37  	// were any problems stopping replication. If no replication processes were running, no error is returned.
    38  	StopReplica(ctx *sql.Context) error
    39  
    40  	// SetReplicationSourceOptions configures the binlog replica controller with the specified source options. The
    41  	// replica controller must store this configuration. If any errors are encountered processing and storing the
    42  	// configuration options, an error is returned.
    43  	SetReplicationSourceOptions(ctx *sql.Context, options []ReplicationOption) error
    44  
    45  	// SetReplicationFilterOptions configures the binlog replica controller with the specified filter options. Although
    46  	// the official MySQL implementation does *NOT* persist these options, the replica controller should persist them.
    47  	// (MySQL requires these options to be manually set after every server restart, or to be specified as command line
    48  	// arguments when starting the MySQL process.) If any errors are encountered processing and storing the filter
    49  	// options, an error is returned.
    50  	SetReplicationFilterOptions(ctx *sql.Context, options []ReplicationOption) error
    51  
    52  	// GetReplicaStatus returns the current status of the replica, or nil if no replication processes are running. If
    53  	// any problems are encountered assembling the replica's status, an error is returned.
    54  	GetReplicaStatus(ctx *sql.Context) (*ReplicaStatus, error)
    55  
    56  	// ResetReplica resets the state for the replica. When the |resetAll| parameter is false, a "soft" or minimal reset
    57  	// is performed – replication errors are reset, but connection information and filters are NOT reset. If |resetAll|
    58  	// is true, a "hard" reset is performed – replication filters are removed, replication source options are removed,
    59  	// and `SHOW REPLICA STATUS` shows no results. If replication is currently running, this function should return an
    60  	// error indicating that replication needs to be stopped before it can be reset. If any errors were encountered
    61  	// resetting the replica state, an error is returned, otherwise nil is returned if the reset was successful.
    62  	ResetReplica(ctx *sql.Context, resetAll bool) error
    63  }
    64  
    65  // ReplicaStatus stores the status of a single binlog replica and is returned by `SHOW REPLICA STATUS`.
    66  // https://dev.mysql.com/doc/refman/8.0/en/show-replica-status.html
    67  type ReplicaStatus struct {
    68  	SourceHost            string
    69  	SourceUser            string
    70  	SourcePort            uint
    71  	ConnectRetry          uint32
    72  	SourceRetryCount      uint64
    73  	ReplicaIoRunning      string
    74  	ReplicaSqlRunning     string
    75  	LastSqlErrNumber      uint   // Alias for LastErrNumber
    76  	LastSqlError          string // Alias for LastError
    77  	LastIoErrNumber       uint
    78  	LastIoError           string
    79  	SourceServerId        string
    80  	SourceServerUuid      string
    81  	LastSqlErrorTimestamp *time.Time
    82  	LastIoErrorTimestamp  *time.Time
    83  	RetrievedGtidSet      string
    84  	ExecutedGtidSet       string
    85  	AutoPosition          bool
    86  	ReplicateDoTables     []string
    87  	ReplicateIgnoreTables []string
    88  }
    89  
    90  type BinlogReplicaCatalog interface {
    91  	IsBinlogReplicaCatalog() bool
    92  	GetBinlogReplicaController() BinlogReplicaController
    93  }
    94  
    95  const (
    96  	ReplicaIoNotRunning  = "No"
    97  	ReplicaIoConnecting  = "Connecting"
    98  	ReplicaIoRunning     = "Yes"
    99  	ReplicaSqlNotRunning = "No"
   100  	ReplicaSqlRunning    = "Yes"
   101  )
   102  
   103  // ReplicationOption represents a single option for replication configuration, as specified through the
   104  // CHANGE REPLICATION SOURCE TO command: https://dev.mysql.com/doc/refman/8.0/en/change-replication-source-to.html
   105  type ReplicationOption struct {
   106  	Name  string
   107  	Value ReplicationOptionValue
   108  }
   109  
   110  // ReplicationOptionValue defines an interface for configuration option values for binlog replication. It holds the
   111  // values of options for configuring the replication source (i.e. "CHANGE REPLICATION SOURCE TO" options) and for
   112  // replication filtering (i.g. "SET REPLICATION FILTER" options).
   113  type ReplicationOptionValue interface {
   114  	fmt.Stringer
   115  
   116  	// GetValue returns the raw, untyped option value. This method should generally not be used; callers should instead
   117  	// find the specific type implementing the ReplicationOptionValue interface and use its functions in order to get
   118  	// typed values.
   119  	GetValue() interface{}
   120  }
   121  
   122  // StringReplicationOptionValue is a ReplicationOptionValue implementation that holds a string value.
   123  type StringReplicationOptionValue struct {
   124  	Value string
   125  }
   126  
   127  var _ ReplicationOptionValue = (*StringReplicationOptionValue)(nil)
   128  
   129  func (ov StringReplicationOptionValue) GetValue() interface{} {
   130  	return ov.GetValueAsString()
   131  }
   132  
   133  func (ov StringReplicationOptionValue) GetValueAsString() string {
   134  	return ov.Value
   135  }
   136  
   137  // String implements the Stringer interface and returns a string representation of this option value.
   138  func (ov StringReplicationOptionValue) String() string {
   139  	return ov.Value
   140  }
   141  
   142  // TableNamesReplicationOptionValue is a ReplicationOptionValue implementation that holds a list of table names for
   143  // its value.
   144  type TableNamesReplicationOptionValue struct {
   145  	Value []sql.UnresolvedTable
   146  }
   147  
   148  var _ ReplicationOptionValue = (*TableNamesReplicationOptionValue)(nil)
   149  
   150  func (ov TableNamesReplicationOptionValue) GetValue() interface{} {
   151  	return ov.GetValueAsTableList()
   152  }
   153  
   154  func (ov TableNamesReplicationOptionValue) GetValueAsTableList() []sql.UnresolvedTable {
   155  	return ov.Value
   156  }
   157  
   158  // String implements the Stringer interface and returns a string representation of this option value.
   159  func (ov TableNamesReplicationOptionValue) String() string {
   160  	sb := strings.Builder{}
   161  	for i, urt := range ov.Value {
   162  		if i > 0 {
   163  			sb.WriteString(", ")
   164  		}
   165  		if urt.Database().Name() != "" {
   166  			sb.WriteString(urt.Database().Name())
   167  			sb.WriteString(".")
   168  		}
   169  		sb.WriteString(urt.Name())
   170  	}
   171  	return sb.String()
   172  }
   173  
   174  // IntegerReplicationOptionValue is a ReplicationOptionValue implementation that holds an integer value.
   175  type IntegerReplicationOptionValue struct {
   176  	Value int
   177  }
   178  
   179  var _ ReplicationOptionValue = (*IntegerReplicationOptionValue)(nil)
   180  
   181  func (ov IntegerReplicationOptionValue) GetValue() interface{} {
   182  	return ov.GetValueAsInt()
   183  }
   184  
   185  func (ov IntegerReplicationOptionValue) GetValueAsInt() int {
   186  	return ov.Value
   187  }
   188  
   189  // String implements the Stringer interface and returns a string representation of this option value.
   190  func (ov IntegerReplicationOptionValue) String() string {
   191  	return strconv.Itoa(ov.Value)
   192  }
   193  
   194  // NewReplicationOption creates a new ReplicationOption instance, with the specified |name| and |value|.
   195  func NewReplicationOption(name string, value ReplicationOptionValue) *ReplicationOption {
   196  	return &ReplicationOption{
   197  		Name:  name,
   198  		Value: value,
   199  	}
   200  }