Class: Innodb::LogBlock
- Inherits:
-
Object
- Object
- Innodb::LogBlock
- Extended by:
- Forwardable
- Defined in:
- lib/innodb/log_block.rb
Defined Under Namespace
Constant Summary collapse
- BLOCK_SIZE =
Log blocks are fixed-length at 512 bytes in InnoDB.
512
- HEADER_OFFSET =
Offset of the header within the log block.
0
- HEADER_SIZE =
The size of the block header.
4 + 2 + 2 + 4
- TRAILER_OFFSET =
Offset of the trailer within ths log block.
BLOCK_SIZE - 4
- TRAILER_SIZE =
The size of the block trailer.
4
- DATA_OFFSET =
Offset of the start of data in the block.
HEADER_SIZE
- DATA_SIZE =
Size of the space available for log records.
BLOCK_SIZE - HEADER_SIZE - TRAILER_SIZE
- HEADER_FLUSH_BIT_MASK =
Mask used to get the flush bit in the header.
0x80000000
Instance Method Summary collapse
-
#calculate_checksum ⇒ Object
Calculate the checksum of the block using InnoDB’s log block checksum algorithm.
-
#corrupt? ⇒ Boolean
Is the block corrupt? Calculate the checksum of the block and compare to the stored checksum; return true or false.
-
#cursor(offset) ⇒ Object
Return an BufferCursor object positioned at a specific offset.
-
#data(offset = DATA_OFFSET) ⇒ Object
Return a slice of actual block data (that is, excluding header and trailer) starting at the given offset.
-
#dump ⇒ Object
Dump the contents of a log block for debugging purposes.
-
#header ⇒ Object
Return the log block header.
-
#initialize(buffer) ⇒ LogBlock
constructor
Initialize a log block by passing in a 512-byte buffer containing the raw log block contents.
-
#trailer ⇒ Object
Return the log block trailer.
Constructor Details
#initialize(buffer) ⇒ LogBlock
Initialize a log block by passing in a 512-byte buffer containing the raw log block contents.
50 51 52 53 54 |
# 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 |
Instance Method Details
#calculate_checksum ⇒ Object
Calculate the checksum of the block using InnoDB’s log block checksum algorithm.
102 103 104 105 106 107 108 109 110 |
# 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? ⇒ Boolean
Is the block corrupt? Calculate the checksum of the block and compare to the stored checksum; return true or false.
114 115 116 |
# File 'lib/innodb/log_block.rb', line 114 def corrupt? checksum != calculate_checksum end |
#cursor(offset) ⇒ Object
Return an BufferCursor object positioned at a specific offset.
57 58 59 |
# File 'lib/innodb/log_block.rb', line 57 def cursor(offset) BufferCursor.new(@buffer, offset) end |
#data(offset = DATA_OFFSET) ⇒ Object
Return a slice of actual block data (that is, excluding header and trailer) starting at the given offset.
82 83 84 85 86 87 88 89 |
# 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 ⇒ Object
Dump the contents of a log block for debugging purposes.
119 120 121 122 123 124 125 126 127 |
# File 'lib/innodb/log_block.rb', line 119 def dump puts puts "header:" pp header puts puts "trailer:" pp trailer end |
#header ⇒ Object
Return the log block header.
62 63 64 65 66 67 68 69 70 71 72 |
# 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 ⇒ Object
Return the log block trailer.
92 93 94 95 96 |
# 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 |