vitess.io/vitess@v0.16.2/go/mysql/binlog_event_mariadb.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 mysql
    18  
    19  import (
    20  	"encoding/binary"
    21  
    22  	"vitess.io/vitess/go/vt/proto/vtrpc"
    23  	"vitess.io/vitess/go/vt/vterrors"
    24  )
    25  
    26  // mariadbBinlogEvent wraps a raw packet buffer and provides methods to examine
    27  // it by implementing BinlogEvent. Some methods are pulled in from
    28  // binlogEvent.
    29  type mariadbBinlogEvent struct {
    30  	binlogEvent
    31  	semiSyncAckRequested bool
    32  }
    33  
    34  // NewMariadbBinlogEventWithSemiSyncInfo creates a BinlogEvent instance from given byte array
    35  func NewMariadbBinlogEventWithSemiSyncInfo(buf []byte, semiSyncAckRequested bool) BinlogEvent {
    36  	return mariadbBinlogEvent{binlogEvent: binlogEvent(buf), semiSyncAckRequested: semiSyncAckRequested}
    37  }
    38  
    39  // NewMariadbBinlogEvent creates a BinlogEvent instance from given byte array
    40  func NewMariadbBinlogEvent(buf []byte) BinlogEvent {
    41  	return mariadbBinlogEvent{binlogEvent: binlogEvent(buf)}
    42  }
    43  
    44  // IsSemiSyncAckRequested implements BinlogEvent.IsSemiSyncAckRequested().
    45  func (ev mariadbBinlogEvent) IsSemiSyncAckRequested() bool {
    46  	return ev.semiSyncAckRequested
    47  }
    48  
    49  // IsGTID implements BinlogEvent.IsGTID().
    50  func (ev mariadbBinlogEvent) IsGTID() bool {
    51  	return ev.Type() == eMariaGTIDEvent
    52  }
    53  
    54  // GTID implements BinlogEvent.GTID().
    55  //
    56  // Expected format:
    57  //
    58  //	# bytes   field
    59  //	8         sequence number
    60  //	4         domain ID
    61  //	1         flags2
    62  func (ev mariadbBinlogEvent) GTID(f BinlogFormat) (GTID, bool, error) {
    63  	const FLStandalone = 1
    64  
    65  	data := ev.Bytes()[f.HeaderLength:]
    66  	flags2 := data[8+4]
    67  
    68  	return MariadbGTID{
    69  		Sequence: binary.LittleEndian.Uint64(data[:8]),
    70  		Domain:   binary.LittleEndian.Uint32(data[8 : 8+4]),
    71  		Server:   ev.ServerID(),
    72  	}, flags2&FLStandalone == 0, nil
    73  }
    74  
    75  // PreviousGTIDs implements BinlogEvent.PreviousGTIDs().
    76  func (ev mariadbBinlogEvent) PreviousGTIDs(f BinlogFormat) (Position, error) {
    77  	return Position{}, vterrors.Errorf(vtrpc.Code_INTERNAL, "MariaDB should not provide PREVIOUS_GTIDS_EVENT events")
    78  }
    79  
    80  // StripChecksum implements BinlogEvent.StripChecksum().
    81  func (ev mariadbBinlogEvent) StripChecksum(f BinlogFormat) (BinlogEvent, []byte, error) {
    82  	switch f.ChecksumAlgorithm {
    83  	case BinlogChecksumAlgOff, BinlogChecksumAlgUndef:
    84  		// There is no checksum.
    85  		return ev, nil, nil
    86  	default:
    87  		// Checksum is the last 4 bytes of the event buffer.
    88  		data := ev.Bytes()
    89  		length := len(data)
    90  		checksum := data[length-4:]
    91  		data = data[:length-4]
    92  		return mariadbBinlogEvent{binlogEvent: binlogEvent(data)}, checksum, nil
    93  	}
    94  }