Class: MysqlBinlog::BinlogEventParser

Inherits:
Object
  • Object
show all
Defined in:
lib/mysql_binlog/binlog_event_parser.rb

Overview

Parse binary log events from a provided binary log. Must be driven externally, but handles all the details of parsing an event header and the content of the various event types.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(binlog_instance) ⇒ BinlogEventParser

Returns a new instance of BinlogEventParser.



169
170
171
172
173
174
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 169

def initialize(binlog_instance)
  @binlog = binlog_instance
  @reader = binlog_instance.reader
  @parser = binlog_instance.field_parser
  @table_map = {}
end

Instance Attribute Details

#binlogObject

The binary log object this event parser will parse events from.



160
161
162
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 160

def binlog
  @binlog
end

#parserObject

The binary log field parser extracted from the binlog object for convenience.



167
168
169
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 167

def parser
  @parser
end

#readerObject

The binary log reader extracted from the binlog object for convenience.



163
164
165
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 163

def reader
  @reader
end

Instance Method Details

#event_headerObject

Parse an event header, which is consistent for all event types.

Documented in sql/log_event.h line ~749 as “Common-Header”

Implemented in sql/log_event.cc line ~936 in Log_event::write_header



181
182
183
184
185
186
187
188
189
190
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 181

def event_header
  header = {}
  header[:timestamp]      = parser.read_uint32
  header[:event_type]     = EVENT_TYPES[parser.read_uint8]
  header[:server_id]      = parser.read_uint32
  header[:event_length]   = parser.read_uint32
  header[:next_position]  = parser.read_uint32
  header[:flags] = parser.read_uint_bitmap_by_size_and_name(2, EVENT_HEADER_FLAGS)
  header
end

#format_description_event(header) ⇒ Object

Parse fields for a Format_description event.

Implemented in sql/log_event.cc line ~4123 in Format_description_log_event::write



195
196
197
198
199
200
201
202
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 195

def format_description_event(header)
  fields = {}
  fields[:binlog_version]   = parser.read_uint16
  fields[:server_version]   = parser.read_nstringz(50)
  fields[:create_timestamp] = parser.read_uint32
  fields[:header_length]    = parser.read_uint8
  fields
end

#generic_rows_event(header) ⇒ Object Also known as: write_rows_event, update_rows_event, delete_rows_event

Parse fields for any of the row-based replication row events:

  • Write_rows which is used for INSERT.

  • Update_rows which is used for UPDATE.

  • Delete_rows which is used for DELETE.

Implemented in sql/log_event.cc line ~8039 in Rows_log_event::write_data_header and Rows_log_event::write_data_body



494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 494

def generic_rows_event(header)
  fields = {}
  table_id = parser.read_uint48
  fields[:table] = @table_map[table_id]
  fields[:flags] = parser.read_uint_bitmap_by_size_and_name(2, GENERIC_ROWS_EVENT_FLAGS)
  columns = parser.read_varint
  columns_used = {}
  case header[:event_type]
  when :write_rows_event
    columns_used[:after]  = parser.read_bit_array(columns)
  when :delete_rows_event
    columns_used[:before] = parser.read_bit_array(columns)
  when :update_rows_event
    columns_used[:before] = parser.read_bit_array(columns)
    columns_used[:after]  = parser.read_bit_array(columns)
  end
  fields[:row_image] = _generic_rows_event_row_images(header, fields, columns_used)
  fields
end

#intvar_event(header) ⇒ Object

Parse fields for an Intvar event.

Implemented in sql/log_event.cc line ~5326 in Intvar_log_event::write



288
289
290
291
292
293
294
295
296
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 288

def intvar_event(header)
  fields = {}

  fields[:intvar_type]  = parser.read_uint8
  fields[:intvar_name]  = INTVAR_EVENT_INTVAR_TYPES[fields[:intvar_type]]
  fields[:intvar_value] = parser.read_uint64

  fields
end

#query_event(header) ⇒ Object

Parse fields for a Query event.

Implemented in sql/log_event.cc line ~2214 in Query_log_event::write



272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 272

def query_event(header)
  fields = {}
  fields[:thread_id] = parser.read_uint32
  fields[:elapsed_time] = parser.read_uint32
  db_length = parser.read_uint8
  fields[:error_code] = parser.read_uint16
  fields[:status] = _query_event_status(header, fields)
  fields[:db] = parser.read_nstringz(db_length + 1)
  query_length = reader.remaining(header)
  fields[:query] = reader.read([query_length, binlog.max_query_length].min)
  fields
end

#rand_event(header) ⇒ Object

Parse fields for an Rand event.

Implemented in sql/log_event.cc line ~5454 in Rand_log_event::write



310
311
312
313
314
315
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 310

def rand_event(header)
  fields = {}
  fields[:seed1] = parser.read_uint64
  fields[:seed2] = parser.read_uint64
  fields
end

#rotate_event(header) ⇒ Object

Parse fields for a Rotate event.

Implemented in sql/log_event.cc line ~5157 in Rotate_log_event::write



207
208
209
210
211
212
213
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 207

def rotate_event(header)
  fields = {}
  fields[:pos] = parser.read_uint64
  name_length = reader.remaining(header)
  fields[:name] = parser.read_nstring(name_length)
  fields
end

#table_map_event(header) ⇒ Object

Parse fields for a Table_map event.

Implemented in sql/log_event.cc line ~8638 in Table_map_log_event::write_data_header and Table_map_log_event::write_data_body



371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 371

def table_map_event(header)
  fields = {}
  fields[:table_id] = parser.read_uint48
  fields[:flags] = parser.read_uint_bitmap_by_size_and_name(2, TABLE_MAP_EVENT_FLAGS)
  map_entry = @table_map[fields[:table_id]] = {}
  map_entry[:db] = parser.read_lpstringz
  map_entry[:table] = parser.read_lpstringz
  columns = parser.read_varint
  columns_type = parser.read_uint8_array(columns).map { |c| MYSQL_TYPES[c] }
   = (columns_type)
  columns_nullable = parser.read_bit_array(columns)

  # Remap overloaded types before we piece together the entire event.
  columns.times do |c|
    if [c] and [c][:type]
      columns_type[c] = [c][:type]
      [c].delete :type
    end
  end

  map_entry[:columns] = columns.times.map do |c|
    {
      :type     => columns_type[c],
      :nullable => columns_nullable[c],
      :metadata => [c],
    }
  end

  fields[:map_entry] = map_entry
  fields
end

#table_metadata_event(header) ⇒ Object

Parse fields for a Table_metadata event, which is specific to Twitter MySQL releases at the moment.

Implemented in sql/log_event.cc line ~8772 (in Twitter MySQL) in Table_metadata_log_event::write_data_header and Table_metadata_log_event::write_data_body



409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 409

def (header)
  fields = {}
  table_id = parser.read_uint48
  columns = parser.read_uint16

  fields[:table] = @table_map[table_id]
  fields[:flags] = parser.read_uint16
  fields[:columns] = columns.times.map do |c|
    descriptor_length = parser.read_uint32
    @table_map[table_id][:columns][c][:description] = {
      :type => MYSQL_TYPES[parser.read_uint8],
      :length => parser.read_uint32,
      :scale => parser.read_uint8,
      :character_set => COLLATION[parser.read_uint16],
      :flags => parser.read_uint_bitmap_by_size_and_name(2,
                TABLE_METADATA_EVENT_COLUMN_FLAGS),
      :name => parser.read_varstring,
      :type_name => parser.read_varstring,
      :comment => parser.read_varstring,
    }
  end
  fields
end

#xid_event(header) ⇒ Object

Parse fields for an Xid event.

Implemented in sql/log_event.cc line ~5559 in Xid_log_event::write



301
302
303
304
305
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 301

def xid_event(header)
  fields = {}
  fields[:xid] = parser.read_uint64
  fields
end