2017-05-06 02:21:12 +03:00
|
|
|
/*
|
|
|
|
Copyright 2017 Google Inc.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreedto in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2017-05-18 19:25:15 +03:00
|
|
|
package mysql
|
2014-07-26 00:48:19 +04:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
2019-02-27 13:06:46 +03:00
|
|
|
|
|
|
|
"vitess.io/vitess/go/vt/proto/vtrpc"
|
|
|
|
"vitess.io/vitess/go/vt/vterrors"
|
2014-07-26 00:48:19 +04:00
|
|
|
)
|
|
|
|
|
|
|
|
const mariadbFlavorID = "MariaDB"
|
|
|
|
|
2014-09-04 04:43:40 +04:00
|
|
|
// parseMariadbGTID is registered as a GTID parser.
|
2014-07-26 00:48:19 +04:00
|
|
|
func parseMariadbGTID(s string) (GTID, error) {
|
|
|
|
// Split into parts.
|
|
|
|
parts := strings.Split(s, "-")
|
|
|
|
if len(parts) != 3 {
|
2019-02-27 13:06:46 +03:00
|
|
|
return nil, vterrors.Errorf(vtrpc.Code_INTERNAL, "invalid MariaDB GTID (%v): expecting Domain-Server-Sequence", s)
|
2014-07-26 00:48:19 +04:00
|
|
|
}
|
|
|
|
|
2014-08-06 04:09:00 +04:00
|
|
|
// Parse Domain ID.
|
|
|
|
Domain, err := strconv.ParseUint(parts[0], 10, 32)
|
2014-07-26 00:48:19 +04:00
|
|
|
if err != nil {
|
2019-02-27 13:06:46 +03:00
|
|
|
return nil, vterrors.Wrapf(err, "invalid MariaDB GTID Domain ID (%v)", parts[0])
|
2014-07-26 00:48:19 +04:00
|
|
|
}
|
|
|
|
|
2014-08-06 04:09:00 +04:00
|
|
|
// Parse Server ID.
|
|
|
|
Server, err := strconv.ParseUint(parts[1], 10, 32)
|
2014-07-26 00:48:19 +04:00
|
|
|
if err != nil {
|
2019-02-27 13:06:46 +03:00
|
|
|
return nil, vterrors.Wrapf(err, "invalid MariaDB GTID Server ID (%v)", parts[1])
|
2014-07-26 00:48:19 +04:00
|
|
|
}
|
|
|
|
|
2014-08-06 04:09:00 +04:00
|
|
|
// Parse Sequence number.
|
|
|
|
Sequence, err := strconv.ParseUint(parts[2], 10, 64)
|
2014-07-26 00:48:19 +04:00
|
|
|
if err != nil {
|
2019-02-27 13:06:46 +03:00
|
|
|
return nil, vterrors.Wrapf(err, "invalid MariaDB GTID Sequence number (%v)", parts[2])
|
2014-07-26 00:48:19 +04:00
|
|
|
}
|
|
|
|
|
2014-08-06 04:09:00 +04:00
|
|
|
return MariadbGTID{
|
|
|
|
Domain: uint32(Domain),
|
|
|
|
Server: uint32(Server),
|
|
|
|
Sequence: Sequence,
|
2014-07-26 00:48:19 +04:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2014-09-04 04:43:40 +04:00
|
|
|
// parseMariadbGTIDSet is registered as a GTIDSet parser.
|
|
|
|
func parseMariadbGTIDSet(s string) (GTIDSet, error) {
|
2018-10-23 00:21:17 +03:00
|
|
|
gtidStrings := strings.Split(s, ",")
|
|
|
|
gtidSet := make(MariadbGTIDSet, len(gtidStrings))
|
|
|
|
for i, gtidString := range gtidStrings {
|
|
|
|
gtid, err := parseMariadbGTID(gtidString)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
gtidSet[i] = gtid.(MariadbGTID)
|
2014-09-04 23:13:47 +04:00
|
|
|
}
|
2018-10-23 00:21:17 +03:00
|
|
|
return gtidSet, nil
|
2014-09-04 04:43:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// MariadbGTID implements GTID.
|
2014-08-06 04:09:00 +04:00
|
|
|
type MariadbGTID struct {
|
2014-09-04 04:43:40 +04:00
|
|
|
// Domain is the ID number of the domain within which sequence numbers apply.
|
|
|
|
Domain uint32
|
|
|
|
// Server is the ID of the server that generated the transaction.
|
|
|
|
Server uint32
|
|
|
|
// Sequence is the sequence number of the transaction within the domain.
|
2014-08-06 04:09:00 +04:00
|
|
|
Sequence uint64
|
2014-07-26 00:48:19 +04:00
|
|
|
}
|
|
|
|
|
2018-10-23 00:21:17 +03:00
|
|
|
// MariadbGTIDSet implements GTIDSet
|
|
|
|
type MariadbGTIDSet []MariadbGTID
|
|
|
|
|
2014-07-26 00:48:19 +04:00
|
|
|
// String implements GTID.String().
|
2014-08-06 04:09:00 +04:00
|
|
|
func (gtid MariadbGTID) String() string {
|
|
|
|
return fmt.Sprintf("%d-%d-%d", gtid.Domain, gtid.Server, gtid.Sequence)
|
2014-07-26 00:48:19 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Flavor implements GTID.Flavor().
|
2014-08-06 04:09:00 +04:00
|
|
|
func (gtid MariadbGTID) Flavor() string {
|
2014-07-26 00:48:19 +04:00
|
|
|
return mariadbFlavorID
|
|
|
|
}
|
|
|
|
|
2014-09-04 04:43:40 +04:00
|
|
|
// SequenceDomain implements GTID.SequenceDomain().
|
2015-04-30 23:58:15 +03:00
|
|
|
func (gtid MariadbGTID) SequenceDomain() interface{} {
|
|
|
|
return gtid.Domain
|
2014-09-04 04:43:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// SourceServer implements GTID.SourceServer().
|
2015-04-30 23:58:15 +03:00
|
|
|
func (gtid MariadbGTID) SourceServer() interface{} {
|
|
|
|
return gtid.Server
|
2014-09-04 04:43:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// SequenceNumber implements GTID.SequenceNumber().
|
2015-04-30 23:58:15 +03:00
|
|
|
func (gtid MariadbGTID) SequenceNumber() interface{} {
|
2014-09-04 04:43:40 +04:00
|
|
|
return gtid.Sequence
|
|
|
|
}
|
|
|
|
|
|
|
|
// GTIDSet implements GTID.GTIDSet().
|
|
|
|
func (gtid MariadbGTID) GTIDSet() GTIDSet {
|
2018-10-23 00:21:17 +03:00
|
|
|
return MariadbGTIDSet{gtid}
|
|
|
|
}
|
|
|
|
|
|
|
|
// String implements GTIDSet.String()
|
|
|
|
func (gtidSet MariadbGTIDSet) String() string {
|
|
|
|
s := make([]string, len(gtidSet))
|
|
|
|
for i, gtid := range gtidSet {
|
|
|
|
s[i] = gtid.String()
|
|
|
|
}
|
|
|
|
return strings.Join(s, ",")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Flavor implements GTIDSet.Flavor()
|
|
|
|
func (gtidSet MariadbGTIDSet) Flavor() string {
|
|
|
|
return mariadbFlavorID
|
2014-09-04 04:43:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// ContainsGTID implements GTIDSet.ContainsGTID().
|
2018-10-23 00:21:17 +03:00
|
|
|
func (gtidSet MariadbGTIDSet) ContainsGTID(other GTID) bool {
|
2014-09-04 04:43:40 +04:00
|
|
|
if other == nil {
|
|
|
|
return true
|
2014-07-26 00:48:19 +04:00
|
|
|
}
|
2014-09-04 04:43:40 +04:00
|
|
|
mdbOther, ok := other.(MariadbGTID)
|
2018-10-23 00:21:17 +03:00
|
|
|
if !ok {
|
2014-09-04 04:43:40 +04:00
|
|
|
return false
|
|
|
|
}
|
2018-10-23 00:21:17 +03:00
|
|
|
for _, gtid := range gtidSet {
|
|
|
|
if gtid.Domain != mdbOther.Domain {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
return gtid.Sequence >= mdbOther.Sequence
|
|
|
|
}
|
|
|
|
return false
|
2014-09-04 04:43:40 +04:00
|
|
|
}
|
2014-07-26 00:48:19 +04:00
|
|
|
|
2014-09-04 04:43:40 +04:00
|
|
|
// Contains implements GTIDSet.Contains().
|
2018-10-23 00:21:17 +03:00
|
|
|
func (gtidSet MariadbGTIDSet) Contains(other GTIDSet) bool {
|
2014-09-04 04:43:40 +04:00
|
|
|
if other == nil {
|
|
|
|
return true
|
2014-07-26 00:48:19 +04:00
|
|
|
}
|
2018-10-23 00:21:17 +03:00
|
|
|
mdbOther, ok := other.(MariadbGTIDSet)
|
|
|
|
if !ok {
|
2014-09-04 04:43:40 +04:00
|
|
|
return false
|
2014-07-26 00:48:19 +04:00
|
|
|
}
|
2018-10-23 00:21:17 +03:00
|
|
|
for _, gtid := range mdbOther {
|
|
|
|
if !gtidSet.ContainsGTID(gtid) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
2014-09-04 04:43:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Equal implements GTIDSet.Equal().
|
2018-10-23 00:21:17 +03:00
|
|
|
func (gtidSet MariadbGTIDSet) Equal(other GTIDSet) bool {
|
|
|
|
mdbOther, ok := other.(MariadbGTIDSet)
|
2014-09-04 04:43:40 +04:00
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
2018-10-23 00:21:17 +03:00
|
|
|
if len(gtidSet) != len(mdbOther) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
for i, gtid := range gtidSet {
|
|
|
|
if gtid != mdbOther[i] {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
2014-09-04 04:43:40 +04:00
|
|
|
}
|
2014-07-26 00:48:19 +04:00
|
|
|
|
2014-09-04 04:43:40 +04:00
|
|
|
// AddGTID implements GTIDSet.AddGTID().
|
2018-10-23 00:21:17 +03:00
|
|
|
func (gtidSet MariadbGTIDSet) AddGTID(other GTID) GTIDSet {
|
2014-09-04 04:43:40 +04:00
|
|
|
mdbOther, ok := other.(MariadbGTID)
|
2018-10-23 00:21:17 +03:00
|
|
|
if !ok || other == nil {
|
|
|
|
return gtidSet
|
|
|
|
}
|
|
|
|
for i, gtid := range gtidSet {
|
|
|
|
if mdbOther.Domain == gtid.Domain {
|
|
|
|
if mdbOther.Sequence > gtid.Sequence {
|
|
|
|
gtidSet[i] = mdbOther
|
|
|
|
}
|
|
|
|
return gtidSet
|
|
|
|
}
|
2014-07-26 00:48:19 +04:00
|
|
|
}
|
2018-10-23 00:21:17 +03:00
|
|
|
return append(gtidSet, mdbOther)
|
2014-07-26 00:48:19 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
gtidParsers[mariadbFlavorID] = parseMariadbGTID
|
2014-09-04 04:43:40 +04:00
|
|
|
gtidSetParsers[mariadbFlavorID] = parseMariadbGTIDSet
|
2014-07-26 00:48:19 +04:00
|
|
|
}
|