class Innodb::LogReader
Constants
- Context
Attributes
checksum[RW]
Whether to checksum blocks. TODO: Hmm, nothing seems to actually set this.
Public Class Methods
new(lsn, group)
click to toggle source
# File lib/innodb/log_reader.rb, line 23 def initialize(lsn, group) @group = group @context = Context.new(buffer: String.new, buffer_lsn: lsn.dup, record_lsn: lsn.dup) end
Public Instance Methods
each_record(follow, wait = 0.5) { |record| ... }
click to toggle source
Call the given block once for each record in the log until the end of the log (or a corrupted block) is reached. If the follow argument is true, retry.
# File lib/innodb/log_reader.rb, line 54 def each_record(follow, wait = 0.5) loop { yield record } rescue EOFError, ChecksumError sleep(wait) && retry if follow end
record()
click to toggle source
Read a record.
# File lib/innodb/log_reader.rb, line 43 def record cursor = BufferCursor.new(self, 0) record = Innodb::LogRecord.new record.read(cursor) record.lsn = reposition(cursor.position) record end
seek(lsn_no)
click to toggle source
Seek to record starting position.
# File lib/innodb/log_reader.rb, line 29 def seek(lsn_no) check_lsn_no(lsn_no) @context.buffer = String.new @context.buffer_lsn.reposition(lsn_no, @group) @context.record_lsn = @context.buffer_lsn.dup self end
slice(position, length)
click to toggle source
Read a slice of log data (that is, log data used for records).
# File lib/innodb/log_reader.rb, line 61 def slice(position, length) buffer = @context.buffer length = position + length preload(length) if length > buffer.size buffer.slice(position, length - position) end
tell()
click to toggle source
Returns the current LSN
starting position.
# File lib/innodb/log_reader.rb, line 38 def tell @context.record_lsn.no end
Private Instance Methods
check_lsn_no(lsn_no)
click to toggle source
Check if LSN
points to where records may be located.
# File lib/innodb/log_reader.rb, line 73 def check_lsn_no(lsn_no) lsn = @context.record_lsn.dup lsn.reposition(lsn_no, @group) raise "LSN #{lsn_no} is out of bounds" unless lsn.record?(@group) end
get_block(lsn)
click to toggle source
Reads the log block at the given LSN
position.
# File lib/innodb/log_reader.rb, line 89 def get_block(lsn) log_no, block_no, block_offset = lsn.location(@group) [@group.log(log_no).block(block_no), block_offset] end
preload(size)
click to toggle source
Preload the log buffer with enough data to satisfy the requested amount.
# File lib/innodb/log_reader.rb, line 95 def preload(size) buffer = @context.buffer buffer_lsn = @context.buffer_lsn # If reading for the first time, offset points to the start of the # record (somewhere in the block). Otherwise, the block is read as # a whole and offset points to the start of the next block to read. while buffer.size < size block, offset = get_block(buffer_lsn) break if checksum && (corrupt = block.corrupt?) data = offset.zero? ? block.data : block.data(offset) data_length = block.header[:data_length] buffer << data buffer_lsn.advance(data_length - offset, @group) break if data_length < Innodb::LogBlock::BLOCK_SIZE end raise ChecksumError, "Block is corrupted" if corrupt raise EOFError, "End of log reached" if buffer.size < size end
reposition(length)
click to toggle source
Reposition to the beginning of the next record.
# File lib/innodb/log_reader.rb, line 80 def reposition(length) start_lsn_no = @context.record_lsn.no delta_lsn_no = @context.record_lsn.delta(length) @context.record_lsn.advance(delta_lsn_no, @group) @context.buffer.slice!(0, length) [start_lsn_no, start_lsn_no + delta_lsn_no] end