Class: Innodb::Page::FspHdrXdes

Inherits:
Innodb::Page show all
Extended by:
ReadBitsAtOffset
Defined in:
lib/innodb/page/fsp_hdr_xdes.rb

Defined Under Namespace

Classes: Flags, Header

Constant Summary collapse

FLAGS_PAGE_SIZE_SHIFT =

A value added to the adjusted exponent stored in the page size field of the flags in the FSP header.

9

Constants inherited from Innodb::Page

PAGE_TYPE, PAGE_TYPE_BY_VALUE, UNDEFINED_PAGE_NUMBER

Instance Attribute Summary

Attributes inherited from Innodb::Page

#space

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ReadBitsAtOffset

read_bits_at_offset

Methods inherited from Innodb::Page

#checksum_crc32, #checksum_crc32?, #checksum_innodb, #checksum_innodb?, #checksum_invalid?, #checksum_type, #checksum_valid?, #corrupt?, #cursor, #default_page_size?, #each_page_body_byte_as_uint8, #each_page_header_byte_as_uint8, #extent_descriptor?, #fil_header, #fil_trailer, handle, #in_doublewrite_buffer?, #initialize, #inspect, #inspect_header_fields, maybe_undefined, #misplaced?, #misplaced_offset?, #misplaced_space?, #name, parse, #pos_fil_header, #pos_fil_trailer, #pos_page_body, #pos_partial_page_header, register_specialization, #size, #size_fil_header, #size_fil_trailer, #size_page_body, #size_partial_page_header, specialization_for, specialization_for?, #torn?, undefined?

Constructor Details

This class inherits a constructor from Innodb::Page

Class Method Details

.decode_flags(flags) ⇒ Object

Decode the “flags” field in the FSP header, returning a hash of useful decodings of the flags (based on MySQl 5.6 definitions). The flags are:

Offset Size Description 0 1 Post-Antelope Flag. 1 4 Compressed Page Size (zip_size). This is stored as a

power of 2, minus 9. Since 0 is reserved to mean "not
compressed", the minimum value is 1, thus making the
smallest page size 1024 (2 ** (9 + 1)).

5 1 Atomic Blobs Flag. 6 4 System Page Size (innodb_page_size, UNIV_PAGE_SIZE).

The setting of the system page size when the tablespace
was created, stored in the same format as the compressed
page size above.

10 1 Data Directory Flag.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 74

def self.decode_flags(flags)
  system_page_size =
    shift_page_size(read_bits_at_offset(flags, 4, 6)) ||
    Innodb::Space::DEFAULT_PAGE_SIZE
  compressed_page_size = shift_page_size(read_bits_at_offset(flags, 4, 1))

  Flags.new(
    system_page_size: system_page_size,
    compressed: compressed_page_size ? false : true,
    page_size: compressed_page_size || system_page_size,
    post_antelope: read_bits_at_offset(flags, 1, 0) == 1,
    atomic_blobs: read_bits_at_offset(flags, 1, 5) == 1,
    data_directory: read_bits_at_offset(flags, 1, 10) == 1,
    value: flags
  )
end

.shift_page_size(page_size_shifted) ⇒ Object



54
55
56
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 54

def self.shift_page_size(page_size_shifted)
  (1 << (FLAGS_PAGE_SIZE_SHIFT + page_size_shifted)) if page_size_shifted != 0
end

Instance Method Details

#dumpObject

Dump the contents of a page for debugging purposes.



191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 191

def dump
  super

  puts "fsp header:"
  pp fsp_header
  puts

  puts "xdes entries:"
  each_xdes do |xdes|
    pp xdes
  end
  puts
end

#each_listObject

Iterate through all lists in the file space.



143
144
145
146
147
148
149
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 143

def each_list
  return enum_for(:each_list) unless block_given?

  fsp_header.to_h.each do |key, value|
    yield key, value if value.is_a?(Innodb::List)
  end
end

#each_region {|Region.new( offset: pos_fsp_header, length: size_fsp_header, name: :fsp_header, info: "FSP Header" )| ... } ⇒ Object

Yields:



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 165

def each_region(&block)
  return enum_for(:each_region) unless block_given?

  super(&block)

  yield Region.new(
    offset: pos_fsp_header,
    length: size_fsp_header,
    name: :fsp_header,
    info: "FSP Header"
  )

  each_xdes do |xdes|
    state = xdes.state || "unused"
    yield Region.new(
      offset: xdes.offset,
      length: size_xdes_entry,
      name: "xdes_#{state}".to_sym,
      info: "Extent Descriptor (#{state})"
    )
  end

  nil
end

#each_xdesObject

Iterate through all XDES entries in order. This is useful for debugging, but each of these entries is actually a node in some other list. The state field in the XDES entry indicates which type of list it is present in, although not necessarily which list (e.g. :fseg).



155
156
157
158
159
160
161
162
163
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 155

def each_xdes
  return enum_for(:each_xdes) unless block_given?

  cursor(pos_xdes_array).name("xdes_array") do |c|
    entries_in_xdes_array.times do
      yield Innodb::Xdes.new(self, c)
    end
  end
end

#entries_in_xdes_arrayObject

The number of entries in the XDES array. Defined as page size divided by extent size.



109
110
111
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 109

def entries_in_xdes_array
  size / space.pages_per_extent
end

#fsp_headerObject

Read the FSP (filespace) header, which contains a few counters and flags, as well as list base nodes for each list maintained in the filespace.



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 123

def fsp_header
  @fsp_header ||= cursor(pos_fsp_header).name("fsp") do |c|
    Header.new(
      space_id: c.name("space_id") { c.read_uint32 },
      unused: c.name("unused") { c.read_uint32 },
      size: c.name("size") { c.read_uint32 },
      free_limit: c.name("free_limit") { c.read_uint32 },
      flags: c.name("flags") { self.class.decode_flags(c.read_uint32) },
      frag_n_used: c.name("frag_n_used") { c.read_uint32 },
      free: c.name("list[free]") { Innodb::List::Xdes.new(@space, Innodb::List.get_base_node(c)) },
      free_frag: c.name("list[free_frag]") { Innodb::List::Xdes.new(@space, Innodb::List.get_base_node(c)) },
      full_frag: c.name("list[full_frag]") { Innodb::List::Xdes.new(@space, Innodb::List.get_base_node(c)) },
      first_unused_seg: c.name("first_unused_seg") { c.read_uint64 },
      full_inodes: c.name("list[full_inodes]") { Innodb::List::Inode.new(@space, Innodb::List.get_base_node(c)) },
      free_inodes: c.name("list[free_inodes]") { Innodb::List::Inode.new(@space, Innodb::List.get_base_node(c)) }
    )
  end
end

#pos_fsp_headerObject

The FSP header immediately follows the FIL header.



92
93
94
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 92

def pos_fsp_header
  pos_page_body
end

#pos_xdes_arrayObject

The XDES entry array immediately follows the FSP header.



103
104
105
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 103

def pos_xdes_array
  pos_fsp_header + size_fsp_header
end

#size_fsp_headerObject

The FSP header contains six 32-bit integers, one 64-bit integer, and 5 list base nodes.



98
99
100
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 98

def size_fsp_header
  ((4 * 6) + (1 * 8) + (5 * Innodb::List::BASE_NODE_SIZE))
end

#size_xdes_arrayObject



117
118
119
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 117

def size_xdes_array
  entries_in_xdes_array * size_xdes_entry
end

#size_xdes_entryObject



113
114
115
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 113

def size_xdes_entry
  @size_xdes_entry ||= Innodb::Xdes.new(self, cursor(pos_xdes_array)).size_entry
end