class Innodb::LogBlock

Constants

BLOCK_SIZE

Log blocks are fixed-length at 512 bytes in InnoDB.

DATA_OFFSET

Offset of the start of data in the block.

DATA_SIZE

Size of the space available for log records.

HEADER_FLUSH_BIT_MASK

Mask used to get the flush bit in the header.

HEADER_OFFSET

Offset of the header within the log block.

HEADER_SIZE

The size of the block header.

TRAILER_OFFSET

Offset of the trailer within ths log block.

TRAILER_SIZE

The size of the block trailer.

Trailer

Public Class Methods

new(buffer) click to toggle source

Initialize a log block by passing in a 512-byte buffer containing the raw log block contents.

# File lib/innodb/log_block.rb, line 50
def initialize(buffer)
  raise "Log block buffer provided was not #{BLOCK_SIZE} bytes" unless buffer.size == BLOCK_SIZE

  @buffer = buffer
end

Public Instance Methods

calculate_checksum() click to toggle source

Calculate the checksum of the block using InnoDB’s log block checksum algorithm.

# File lib/innodb/log_block.rb, line 102
def calculate_checksum
  csum = 1
  shift = (0..24).cycle
  cursor(0).each_byte_as_uint8(TRAILER_OFFSET) do |b|
    csum &= 0x7fffffff
    csum += b + (b << shift.next)
  end
  csum
end
corrupt?() click to toggle source

Is the block corrupt? Calculate the checksum of the block and compare to the stored checksum; return true or false.

# File lib/innodb/log_block.rb, line 114
def corrupt?
  checksum != calculate_checksum
end
cursor(offset) click to toggle source

Return an BufferCursor object positioned at a specific offset.

# File lib/innodb/log_block.rb, line 57
def cursor(offset)
  BufferCursor.new(@buffer, offset)
end
data(offset = DATA_OFFSET) click to toggle source

Return a slice of actual block data (that is, excluding header and trailer) starting at the given offset.

# File lib/innodb/log_block.rb, line 82
def data(offset = DATA_OFFSET)
  length = data_length
  length -= TRAILER_SIZE if length == BLOCK_SIZE

  raise "Invalid block data offset" if offset < DATA_OFFSET || offset > length

  @buffer.slice(offset, length - offset)
end
dump() click to toggle source

Dump the contents of a log block for debugging purposes.

# File lib/innodb/log_block.rb, line 119
def dump
  puts
  puts "header:"
  pp header

  puts
  puts "trailer:"
  pp trailer
end
header() click to toggle source

Return the log block header.

# File lib/innodb/log_block.rb, line 62
def header
  @header ||= cursor(HEADER_OFFSET).name("header") do |c|
    Header.new(
      flush: c.name("flush") { c.peek { (c.read_uint32 & HEADER_FLUSH_BIT_MASK).positive? } },
      block_number: c.name("block_number") { c.read_uint32 & ~HEADER_FLUSH_BIT_MASK },
      data_length: c.name("data_length") { c.read_uint16 },
      first_rec_group: c.name("first_rec_group") { c.read_uint16 },
      checkpoint_no: c.name("checkpoint_no") { c.read_uint32 }
    )
  end
end
trailer() click to toggle source

Return the log block trailer.

# File lib/innodb/log_block.rb, line 92
def trailer
  @trailer ||= cursor(TRAILER_OFFSET).name("trailer") do |c|
    Trailer.new(checksum: c.name("checksum") { c.read_uint32 })
  end
end