vitess.io/vitess@v0.16.2/go/mysql/binlog_event.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 "fmt" 21 22 binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" 23 ) 24 25 // BinlogEvent represents a single event from a raw MySQL binlog dump stream. 26 // The implementation is provided by each supported flavor in go/vt/mysqlctl. 27 // 28 // binlog.Streamer receives these events through a mysqlctl.BinlogConnection and 29 // processes them, grouping statements into BinlogTransactions as appropriate. 30 // 31 // Methods that only access header fields can't fail as long as IsValid() 32 // returns true, so they have a single return value. Methods that might fail 33 // even when IsValid() is true return an error value. 34 // 35 // Methods that require information from the initial FORMAT_DESCRIPTION_EVENT 36 // will have a BinlogFormat parameter. 37 // 38 // A BinlogEvent should never be sent over the wire. UpdateStream service 39 // will send BinlogTransactions from these events. 40 type BinlogEvent interface { 41 // IsValid returns true if the underlying data buffer contains a valid 42 // event. This should be called first on any BinlogEvent, and other 43 // methods should only be called if this one returns true. This ensures 44 // you won't get panics due to bounds checking on the byte array. 45 IsValid() bool 46 47 // General protocol events. 48 NextPosition() uint32 49 50 // IsFormatDescription returns true if this is a 51 // FORMAT_DESCRIPTION_EVENT. Do not call StripChecksum before 52 // calling Format (Format returns the BinlogFormat anyway, 53 // required for calling StripChecksum). 54 IsFormatDescription() bool 55 // IsQuery returns true if this is a QUERY_EVENT, which encompasses 56 // all SQL statements. 57 IsQuery() bool 58 // IsXID returns true if this is an XID_EVENT, which is an alternate 59 // form of COMMIT. 60 IsXID() bool 61 // IsStop returns true if this is a STOP_EVENT. 62 IsStop() bool 63 // IsGTID returns true if this is a GTID_EVENT. 64 IsGTID() bool 65 // IsRotate returns true if this is a ROTATE_EVENT. 66 IsRotate() bool 67 // IsIntVar returns true if this is an INTVAR_EVENT. 68 IsIntVar() bool 69 // IsRand returns true if this is a RAND_EVENT. 70 IsRand() bool 71 // IsPreviousGTIDs returns true if this event is a PREVIOUS_GTIDS_EVENT. 72 IsPreviousGTIDs() bool 73 // IsHeartbeat returns true if this event is a HEARTBEAT_EVENT. 74 IsHeartbeat() bool 75 // IsSemiSyncAckRequested returns true if the source requests a semi-sync ack for this event 76 IsSemiSyncAckRequested() bool 77 78 // RBR events. 79 80 // IsTableMap returns true if this is a TABLE_MAP_EVENT. 81 IsTableMap() bool 82 // IsWriteRows returns true if this is a WRITE_ROWS_EVENT. 83 IsWriteRows() bool 84 // IsUpdateRows returns true if this is a UPDATE_ROWS_EVENT. 85 IsUpdateRows() bool 86 // IsDeleteRows returns true if this is a DELETE_ROWS_EVENT. 87 IsDeleteRows() bool 88 89 // Timestamp returns the timestamp from the event header. 90 Timestamp() uint32 91 92 // Format returns a BinlogFormat struct based on the event data. 93 // This is only valid if IsFormatDescription() returns true. 94 Format() (BinlogFormat, error) 95 // GTID returns the GTID from the event, and if this event 96 // also serves as a BEGIN statement. 97 // This is only valid if IsGTID() returns true. 98 GTID(BinlogFormat) (GTID, bool, error) 99 // Query returns a Query struct representing data from a QUERY_EVENT. 100 // This is only valid if IsQuery() returns true. 101 Query(BinlogFormat) (Query, error) 102 // IntVar returns the type and value of the variable for an INTVAR_EVENT. 103 // This is only valid if IsIntVar() returns true. 104 IntVar(BinlogFormat) (byte, uint64, error) 105 // Rand returns the two seed values for a RAND_EVENT. 106 // This is only valid if IsRand() returns true. 107 Rand(BinlogFormat) (uint64, uint64, error) 108 // PreviousGTIDs returns the Position from the event. 109 // This is only valid if IsPreviousGTIDs() returns true. 110 PreviousGTIDs(BinlogFormat) (Position, error) 111 112 // TableID returns the table ID for a TableMap, UpdateRows, 113 // WriteRows or DeleteRows event. 114 TableID(BinlogFormat) uint64 115 // TableMap returns a TableMap struct representing data from a 116 // TABLE_MAP_EVENT. This is only valid if IsTableMapEvent() returns 117 // true. 118 TableMap(BinlogFormat) (*TableMap, error) 119 // Rows returns a Rows struct representing data from a 120 // {WRITE,UPDATE,DELETE}_ROWS_EVENT. This is only valid if 121 // IsWriteRows(), IsUpdateRows(), or IsDeleteRows() returns 122 // true. 123 Rows(BinlogFormat, *TableMap) (Rows, error) 124 // NextLogFile returns the name of the next binary log file & pos. 125 // This is only valid if IsRotate() returns true 126 NextLogFile(BinlogFormat) (string, uint64, error) 127 128 // StripChecksum returns the checksum and a modified event with the 129 // checksum stripped off, if any. If there is no checksum, it returns 130 // the same event and a nil checksum. 131 StripChecksum(BinlogFormat) (ev BinlogEvent, checksum []byte, err error) 132 133 // IsPseudo is for custom implementations of GTID. 134 IsPseudo() bool 135 136 // IsCompressed returns true if a compressed event is found (binlog_transaction_compression=ON) 137 IsCompressed() bool 138 139 // Bytes returns the binary representation of the event 140 Bytes() []byte 141 } 142 143 // BinlogFormat contains relevant data from the FORMAT_DESCRIPTION_EVENT. 144 // This structure is passed to subsequent event types to let them know how to 145 // parse themselves. 146 type BinlogFormat struct { 147 // HeaderSizes is an array of sizes of the headers for each message. 148 HeaderSizes []byte 149 150 // ServerVersion is the name of the MySQL server version. 151 // It starts with something like 5.6.33-xxxx. 152 ServerVersion string 153 154 // FormatVersion is the version number of the binlog file format. 155 // We only support version 4. 156 FormatVersion uint16 157 158 // HeaderLength is the size in bytes of event headers other 159 // than FORMAT_DESCRIPTION_EVENT. Almost always 19. 160 HeaderLength byte 161 162 // ChecksumAlgorithm is the ID number of the binlog checksum algorithm. 163 // See three possible values below. 164 ChecksumAlgorithm byte 165 } 166 167 // IsZero returns true if the BinlogFormat has not been initialized. 168 func (f BinlogFormat) IsZero() bool { 169 return f.FormatVersion == 0 && f.HeaderLength == 0 170 } 171 172 // HeaderSize returns the header size of any event type. 173 func (f BinlogFormat) HeaderSize(typ byte) byte { 174 return f.HeaderSizes[typ-1] 175 } 176 177 // Query contains data from a QUERY_EVENT. 178 type Query struct { 179 Database string 180 Charset *binlogdatapb.Charset 181 SQL string 182 } 183 184 // String pretty-prints a Query. 185 func (q Query) String() string { 186 return fmt.Sprintf("{Database: %q, Charset: %v, SQL: %q}", 187 q.Database, q.Charset, q.SQL) 188 } 189 190 // TableMap contains data from a TABLE_MAP_EVENT. 191 type TableMap struct { 192 // Flags is the table's flags. 193 Flags uint16 194 195 // Database is the database name. 196 Database string 197 198 // Name is the name of the table. 199 Name string 200 201 // Types is an array of MySQL types for the fields. 202 Types []byte 203 204 // CanBeNull's bits are set if the column can be NULL. 205 CanBeNull Bitmap 206 207 // Metadata is an array of uint16, one per column. 208 // It contains a few extra information about each column, 209 // that is dependent on the type. 210 // - If the metadata is not present, this is zero. 211 // - If the metadata is one byte, only the lower 8 bits are used. 212 // - If the metadata is two bytes, all 16 bits are used. 213 Metadata []uint16 214 } 215 216 // Rows contains data from a {WRITE,UPDATE,DELETE}_ROWS_EVENT. 217 type Rows struct { 218 // Flags has the flags from the event. 219 Flags uint16 220 221 // IdentifyColumns describes which columns are included to 222 // identify the row. It is a bitmap indexed by the TableMap 223 // list of columns. 224 // Set for UPDATE and DELETE. 225 IdentifyColumns Bitmap 226 227 // DataColumns describes which columns are included. It is 228 // a bitmap indexed by the TableMap list of columns. 229 // Set for WRITE and UPDATE. 230 DataColumns Bitmap 231 232 // Rows is an array of Row in the event. 233 Rows []Row 234 } 235 236 // Row contains data for a single Row in a Rows event. 237 type Row struct { 238 // NullIdentifyColumns describes which of the identify columns are NULL. 239 // It is only set for UPDATE and DELETE events. 240 NullIdentifyColumns Bitmap 241 242 // NullColumns describes which of the present columns are NULL. 243 // It is only set for WRITE and UPDATE events. 244 NullColumns Bitmap 245 246 // Identify is the raw data for the columns used to identify a row. 247 // It is only set for UPDATE and DELETE events. 248 Identify []byte 249 250 // Data is the raw data. 251 // It is only set for WRITE and UPDATE events. 252 Data []byte 253 } 254 255 // Bitmap is used by the previous structures. 256 type Bitmap struct { 257 // data is the slice this is based on. 258 data []byte 259 260 // count is how many bits we have in the map. 261 count int 262 } 263 264 func newBitmap(data []byte, pos int, count int) (Bitmap, int) { 265 byteSize := (count + 7) / 8 266 return Bitmap{ 267 data: data[pos : pos+byteSize], 268 count: count, 269 }, pos + byteSize 270 } 271 272 // NewServerBitmap returns a bitmap that can hold 'count' bits. 273 func NewServerBitmap(count int) Bitmap { 274 byteSize := (count + 7) / 8 275 return Bitmap{ 276 data: make([]byte, byteSize), 277 count: count, 278 } 279 } 280 281 // Count returns the number of bits in this Bitmap. 282 func (b *Bitmap) Count() int { 283 return b.count 284 } 285 286 // Bit returned the value of a given bit in the Bitmap. 287 func (b *Bitmap) Bit(index int) bool { 288 byteIndex := index / 8 289 bitMask := byte(1 << (uint(index) & 0x7)) 290 return b.data[byteIndex]&bitMask > 0 291 } 292 293 // Set sets the given boolean value. 294 func (b *Bitmap) Set(index int, value bool) { 295 byteIndex := index / 8 296 bitMask := byte(1 << (uint(index) & 0x7)) 297 if value { 298 b.data[byteIndex] |= bitMask 299 } else { 300 b.data[byteIndex] &= 0xff - bitMask 301 } 302 } 303 304 // BitCount returns how many bits are set in the bitmap. 305 // Note values that are not used may be set to 0 or 1, 306 // hence the non-efficient logic. 307 func (b *Bitmap) BitCount() int { 308 sum := 0 309 for i := 0; i < b.count; i++ { 310 if b.Bit(i) { 311 sum++ 312 } 313 } 314 return sum 315 }