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.
- Header
- TRAILER_OFFSET
Offset of the trailer within ths log block.
- TRAILER_SIZE
The size of the block trailer.
- Trailer
Public Class Methods
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 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
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
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
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 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
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
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