Class: Innodb::Log
- Inherits:
-
Object
- Object
- Innodb::Log
- Defined in:
- lib/innodb/log.rb
Overview
An InnoDB transaction log file.
Constant Summary collapse
- LOG_HEADER_BLOCK_MAP =
A map of the name and position of the blocks that form the log header.
{ :LOG_FILE_HEADER => 0, :LOG_CHECKPOINT_1 => 1, :EMPTY => 2, :LOG_CHECKPOINT_2 => 3, }
- LOG_HEADER_BLOCKS =
Number of blocks in the log file header.
LOG_HEADER_BLOCK_MAP.size
- LOG_CHECKPOINT_GROUPS =
Maximum number of log group checkpoints.
32
Instance Attribute Summary collapse
-
#blocks ⇒ Object
readonly
The number of blocks in the the log.
-
#size ⇒ Object
readonly
The size (in bytes) of the log.
Instance Method Summary collapse
-
#block(block_index) ⇒ Object
Return a log block with a given block index as an InnoDB::LogBlock object.
-
#block_cursor(offset) ⇒ Object
Get a cursor to a block in a given offset of the log.
-
#block_data(offset) ⇒ Object
Get the raw byte buffer for a specific block by block offset.
-
#checkpoint ⇒ Object
Return the log checkpoints.
-
#each_block ⇒ Object
Iterate through all log blocks, returning the block index and an InnoDB::LogBlock object for each block.
-
#header ⇒ Object
Return the log header.
-
#initialize(file) ⇒ Log
constructor
Open a log file.
-
#read_checkpoint(c) ⇒ Object
Read a log checkpoint from the given cursor.
Constructor Details
#initialize(file) ⇒ Log
Open a log file.
21 22 23 24 25 |
# File 'lib/innodb/log.rb', line 21 def initialize(file) @file = File.open(file) @size = @file.stat.size @blocks = (@size / Innodb::LogBlock::BLOCK_SIZE) - LOG_HEADER_BLOCKS end |
Instance Attribute Details
#blocks ⇒ Object (readonly)
The number of blocks in the the log.
31 32 33 |
# File 'lib/innodb/log.rb', line 31 def blocks @blocks end |
#size ⇒ Object (readonly)
The size (in bytes) of the log.
28 29 30 |
# File 'lib/innodb/log.rb', line 28 def size @size end |
Instance Method Details
#block(block_index) ⇒ Object
Return a log block with a given block index as an InnoDB::LogBlock object. Blocks are indexed after the log file header, starting from 0.
101 102 103 104 105 |
# File 'lib/innodb/log.rb', line 101 def block(block_index) return nil unless block_index.between?(0, @blocks - 1) offset = (LOG_HEADER_BLOCKS + block_index.to_i) * Innodb::LogBlock::BLOCK_SIZE Innodb::LogBlock.new(block_data(offset)) end |
#block_cursor(offset) ⇒ Object
Get a cursor to a block in a given offset of the log.
41 42 43 |
# File 'lib/innodb/log.rb', line 41 def block_cursor(offset) Innodb::Cursor.new(block_data(offset), 0) end |
#block_data(offset) ⇒ Object
Get the raw byte buffer for a specific block by block offset.
34 35 36 37 38 |
# File 'lib/innodb/log.rb', line 34 def block_data(offset) raise "Invalid block offset" unless (offset % Innodb::LogBlock::BLOCK_SIZE).zero? @file.seek(offset) @file.read(Innodb::LogBlock::BLOCK_SIZE) end |
#checkpoint ⇒ Object
Return the log checkpoints.
85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/innodb/log.rb', line 85 def checkpoint offset1 = LOG_HEADER_BLOCK_MAP[:LOG_CHECKPOINT_1] * Innodb::LogBlock::BLOCK_SIZE offset2 = LOG_HEADER_BLOCK_MAP[:LOG_CHECKPOINT_2] * Innodb::LogBlock::BLOCK_SIZE @checkpoint ||= { :checkpoint_1 => block_cursor(offset1).name("checkpoint_1") do |cursor| read_checkpoint(cursor) end, :checkpoint_2 => block_cursor(offset2).name("checkpoint_2") do |cursor| read_checkpoint(cursor) end } end |
#each_block ⇒ Object
Iterate through all log blocks, returning the block index and an InnoDB::LogBlock object for each block.
109 110 111 112 113 114 |
# File 'lib/innodb/log.rb', line 109 def each_block (0...@blocks).each do |block_index| current_block = block(block_index) yield block_index, current_block if current_block end end |
#header ⇒ Object
Return the log header.
46 47 48 49 50 51 52 53 54 55 |
# File 'lib/innodb/log.rb', line 46 def header offset = LOG_HEADER_BLOCK_MAP[:LOG_FILE_HEADER] * Innodb::LogBlock::BLOCK_SIZE @header ||= block_cursor(offset).name("header") do |c| { :group_id => c.name("group_id") { c.get_uint32 }, :start_lsn => c.name("start_lsn") { c.get_uint64 }, :created_by => c.name("created_by") { c.seek(16).get_bytes(4) } } end end |
#read_checkpoint(c) ⇒ Object
Read a log checkpoint from the given cursor.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/innodb/log.rb', line 58 def read_checkpoint(c) # Log archive related fields (e.g. group_array) are not currently in # use or even read by InnoDB. However, for the sake of completeness, # they are included. { :number => c.name("number") { c.get_uint64 }, :lsn => c.name("lsn") { c.get_uint64 }, :offset => c.name("offset") { c.get_uint32 }, :buffer_size => c.name("buffer_size") { c.get_uint32 }, :archived_lsn => c.name("archived_lsn") { c.get_uint64 }, :group_array => (0 .. LOG_CHECKPOINT_GROUPS - 1).map do |n| c.name("group_array[#{n}]") do { :archived_file_no => c.name("archived_file_no") { c.get_uint32 }, :archived_offset => c.name("archived_offset") { c.get_uint32 }, } end end, :checksum_1 => c.name("checksum_1") { c.get_uint32 }, :checksum_2 => c.name("checksum_2") { c.get_uint32 }, :fsp_free_limit => c.name("fsp_free_limit") { c.get_uint32 }, :fsp_magic => c.name("fsp_magic") { c.get_uint32 }, } end |