vitess.io/vitess@v0.16.2/go/mysql/binlog_event_filepos.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 "fmt" 22 ) 23 24 // filePosBinlogEvent wraps a raw packet buffer and provides methods to examine 25 // it by implementing BinlogEvent. Some methods are pulled in from binlogEvent. 26 type filePosBinlogEvent struct { 27 binlogEvent 28 semiSyncAckRequested bool 29 } 30 31 // newFilePosBinlogEventWithSemiSyncInfo creates a BinlogEvent from given byte array 32 func newFilePosBinlogEventWithSemiSyncInfo(buf []byte, semiSyncAckRequested bool) *filePosBinlogEvent { 33 return &filePosBinlogEvent{binlogEvent: binlogEvent(buf), semiSyncAckRequested: semiSyncAckRequested} 34 } 35 36 // newFilePosBinlogEvent creates a BinlogEvent from given byte array 37 func newFilePosBinlogEvent(buf []byte) *filePosBinlogEvent { 38 return &filePosBinlogEvent{binlogEvent: binlogEvent(buf)} 39 } 40 41 func (*filePosBinlogEvent) GTID(BinlogFormat) (GTID, bool, error) { 42 return nil, false, nil 43 } 44 45 // IsSemiSyncAckRequested implements BinlogEvent.IsSemiSyncAckRequested(). 46 func (ev *filePosBinlogEvent) IsSemiSyncAckRequested() bool { 47 return ev.semiSyncAckRequested 48 } 49 50 func (*filePosBinlogEvent) IsGTID() bool { 51 return false 52 } 53 54 func (*filePosBinlogEvent) PreviousGTIDs(BinlogFormat) (Position, error) { 55 return Position{}, fmt.Errorf("filePos should not provide PREVIOUS_GTIDS_EVENT events") 56 } 57 58 // StripChecksum implements BinlogEvent.StripChecksum(). 59 func (ev *filePosBinlogEvent) StripChecksum(f BinlogFormat) (BinlogEvent, []byte, error) { 60 switch f.ChecksumAlgorithm { 61 case BinlogChecksumAlgOff, BinlogChecksumAlgUndef: 62 // There is no checksum. 63 return ev, nil, nil 64 default: 65 // Checksum is the last 4 bytes of the event buffer. 66 data := ev.Bytes() 67 length := len(data) 68 checksum := data[length-4:] 69 data = data[:length-4] 70 return newFilePosBinlogEvent(data), checksum, nil 71 } 72 } 73 74 // nextPosition returns the next file position of the binlog. 75 // If no information is available, it returns 0. 76 func (ev *filePosBinlogEvent) nextPosition(f BinlogFormat) int { 77 if f.HeaderLength <= 13 { 78 // Dead code. This is just a failsafe. 79 return 0 80 } 81 return int(binary.LittleEndian.Uint32(ev.Bytes()[13:17])) 82 } 83 84 // rotate implements BinlogEvent.Rotate(). 85 // 86 // Expected format (L = total length of event data): 87 // 88 // # bytes field 89 // 8 position 90 // 8:L file 91 func (ev *filePosBinlogEvent) rotate(f BinlogFormat) (int, string) { 92 data := ev.Bytes()[f.HeaderLength:] 93 pos := binary.LittleEndian.Uint64(data[0:8]) 94 file := data[8:] 95 return int(pos), string(file) 96 } 97 98 //---------------------------------------------------------------------------- 99 100 // filePosQueryEvent is a fake begin event. 101 type filePosQueryEvent struct { 102 query string 103 filePosFakeEvent 104 } 105 106 func newFilePosQueryEvent(query string, ts uint32) filePosQueryEvent { 107 return filePosQueryEvent{ 108 query: query, 109 filePosFakeEvent: filePosFakeEvent{ 110 timestamp: ts, 111 }, 112 } 113 } 114 115 func (ev filePosQueryEvent) IsQuery() bool { 116 return true 117 } 118 119 func (ev filePosQueryEvent) Query(BinlogFormat) (Query, error) { 120 return Query{ 121 SQL: ev.query, 122 }, nil 123 } 124 125 func (ev filePosQueryEvent) StripChecksum(f BinlogFormat) (BinlogEvent, []byte, error) { 126 return ev, nil, nil 127 } 128 129 func (ev filePosQueryEvent) Bytes() []byte { 130 return []byte{} 131 } 132 133 //---------------------------------------------------------------------------- 134 135 // filePosFakeEvent is the base class for fake events. 136 type filePosFakeEvent struct { 137 timestamp uint32 138 } 139 140 func (ev filePosFakeEvent) NextPosition() uint32 { 141 return 0 142 } 143 144 func (ev filePosFakeEvent) IsValid() bool { 145 return true 146 } 147 148 func (ev filePosFakeEvent) IsFormatDescription() bool { 149 return false 150 } 151 152 func (ev filePosFakeEvent) IsQuery() bool { 153 return false 154 } 155 156 func (ev filePosFakeEvent) IsXID() bool { 157 return false 158 } 159 160 func (ev filePosFakeEvent) IsStop() bool { 161 return false 162 } 163 164 func (ev filePosFakeEvent) IsSemiSyncAckRequested() bool { 165 return false 166 } 167 168 func (ev filePosFakeEvent) IsGTID() bool { 169 return false 170 } 171 172 func (ev filePosFakeEvent) IsRotate() bool { 173 return false 174 } 175 176 func (ev filePosFakeEvent) IsIntVar() bool { 177 return false 178 } 179 180 func (ev filePosFakeEvent) IsRand() bool { 181 return false 182 } 183 184 func (ev filePosFakeEvent) IsPreviousGTIDs() bool { 185 return false 186 } 187 188 func (ev filePosFakeEvent) IsHeartbeat() bool { 189 return false 190 } 191 192 func (ev filePosFakeEvent) IsTableMap() bool { 193 return false 194 } 195 196 func (ev filePosFakeEvent) IsWriteRows() bool { 197 return false 198 } 199 200 func (ev filePosFakeEvent) IsUpdateRows() bool { 201 return false 202 } 203 204 func (ev filePosFakeEvent) IsDeleteRows() bool { 205 return false 206 } 207 208 func (ev filePosFakeEvent) Timestamp() uint32 { 209 return ev.timestamp 210 } 211 212 func (ev filePosFakeEvent) Format() (BinlogFormat, error) { 213 return BinlogFormat{}, nil 214 } 215 216 func (ev filePosFakeEvent) GTID(BinlogFormat) (GTID, bool, error) { 217 return nil, false, nil 218 } 219 220 func (ev filePosFakeEvent) Query(BinlogFormat) (Query, error) { 221 return Query{}, nil 222 } 223 224 func (ev filePosFakeEvent) IntVar(BinlogFormat) (byte, uint64, error) { 225 return 0, 0, nil 226 } 227 228 func (ev filePosFakeEvent) Rand(BinlogFormat) (uint64, uint64, error) { 229 return 0, 0, nil 230 } 231 232 func (ev filePosFakeEvent) PreviousGTIDs(BinlogFormat) (Position, error) { 233 return Position{}, nil 234 } 235 236 func (ev filePosFakeEvent) TableID(BinlogFormat) uint64 { 237 return 0 238 } 239 240 func (ev filePosFakeEvent) TableMap(BinlogFormat) (*TableMap, error) { 241 return nil, nil 242 } 243 244 func (ev filePosFakeEvent) Rows(BinlogFormat, *TableMap) (Rows, error) { 245 return Rows{}, nil 246 } 247 248 func (ev filePosFakeEvent) NextLogFile(BinlogFormat) (string, uint64, error) { 249 return "", 0, nil 250 } 251 252 func (ev filePosFakeEvent) IsPseudo() bool { 253 return false 254 } 255 256 func (ev filePosFakeEvent) IsCompressed() bool { 257 return false 258 } 259 260 func (ev filePosFakeEvent) Bytes() []byte { 261 return []byte{} 262 } 263 264 //---------------------------------------------------------------------------- 265 266 // filePosGTIDEvent is a fake GTID event for filePos. 267 type filePosGTIDEvent struct { 268 filePosFakeEvent 269 gtid filePosGTID 270 } 271 272 func newFilePosGTIDEvent(file string, pos int, timestamp uint32) filePosGTIDEvent { 273 return filePosGTIDEvent{ 274 filePosFakeEvent: filePosFakeEvent{ 275 timestamp: timestamp, 276 }, 277 gtid: filePosGTID{ 278 file: file, 279 pos: pos, 280 }, 281 } 282 } 283 284 func (ev filePosGTIDEvent) IsGTID() bool { 285 return true 286 } 287 288 func (ev filePosGTIDEvent) StripChecksum(f BinlogFormat) (BinlogEvent, []byte, error) { 289 return ev, nil, nil 290 } 291 292 func (ev filePosGTIDEvent) GTID(BinlogFormat) (GTID, bool, error) { 293 return ev.gtid, false, nil 294 }