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.



124
125
126
127
128
129
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 124

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.



115
116
117
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 115

def binlog
  @binlog
end

#parserObject

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



122
123
124
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 122

def parser
  @parser
end

#readerObject

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



118
119
120
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 118

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



136
137
138
139
140
141
142
143
144
145
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 136

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



150
151
152
153
154
155
156
157
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 150

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



416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 416

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



243
244
245
246
247
248
249
250
251
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 243

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



227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 227

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



265
266
267
268
269
270
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 265

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



162
163
164
165
166
167
168
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 162

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



324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 324

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

#xid_event(header) ⇒ Object

Parse fields for an Xid event.

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



256
257
258
259
260
# File 'lib/mysql_binlog/binlog_event_parser.rb', line 256

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