vitess.io/vitess@v0.16.2/go/mysql/binlog_dump.go (about)

     1  /*
     2  Copyright 2022 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  	"io"
    22  
    23  	vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
    24  	"vitess.io/vitess/go/vt/vterrors"
    25  )
    26  
    27  var (
    28  	// BinglogMagicNumber is 4-byte number at the beginning of every binary log
    29  	BinglogMagicNumber = []byte{0xfe, 0x62, 0x69, 0x6e}
    30  	readPacketErr      = vterrors.Errorf(vtrpcpb.Code_INTERNAL, "error reading BinlogDumpGTID packet")
    31  )
    32  
    33  const (
    34  	BinlogDumpNonBlock    = 0x01
    35  	BinlogThroughPosition = 0x02
    36  	BinlogThroughGTID     = 0x04
    37  )
    38  
    39  func (c *Conn) parseComBinlogDump(data []byte) (logFile string, binlogPos uint32, err error) {
    40  	pos := 1
    41  
    42  	binlogPos, pos, ok := readUint32(data, pos)
    43  	if !ok {
    44  		return logFile, binlogPos, readPacketErr
    45  	}
    46  
    47  	pos += 2 // flags
    48  	pos += 4 // server-id
    49  
    50  	logFile = string(data[pos:])
    51  	return logFile, binlogPos, nil
    52  }
    53  
    54  func (c *Conn) parseComBinlogDumpGTID(data []byte) (logFile string, logPos uint64, position Position, err error) {
    55  	// see https://dev.mysql.com/doc/internals/en/com-binlog-dump-gtid.html
    56  	pos := 1
    57  
    58  	flags2 := binary.LittleEndian.Uint16(data[pos : pos+2])
    59  	pos += 2 // flags
    60  	pos += 4 // server-id
    61  
    62  	fileNameLen, pos, ok := readUint32(data, pos)
    63  	if !ok {
    64  		return logFile, logPos, position, readPacketErr
    65  	}
    66  	logFile = string(data[pos : pos+int(fileNameLen)])
    67  	pos += int(fileNameLen)
    68  
    69  	logPos, pos, ok = readUint64(data, pos)
    70  	if !ok {
    71  		return logFile, logPos, position, readPacketErr
    72  	}
    73  
    74  	if flags2&BinlogDumpNonBlock != 0 {
    75  		return logFile, logPos, position, io.EOF
    76  	}
    77  	if flags2&BinlogThroughGTID != 0 {
    78  		dataSize, pos, ok := readUint32(data, pos)
    79  		if !ok {
    80  			return logFile, logPos, position, readPacketErr
    81  		}
    82  		if gtid := string(data[pos : pos+int(dataSize)]); gtid != "" {
    83  			position, err = DecodePosition(gtid)
    84  			if err != nil {
    85  				return logFile, logPos, position, err
    86  			}
    87  		}
    88  	}
    89  
    90  	return logFile, logPos, position, nil
    91  }