Class: Innodb::Page::FspHdrXdes

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

Overview

A specialized class for FSP_HDR (filespace header) and XDES (extent descriptor) page types. Each tablespace always has an FSP_HDR page as its first page (page 0), and has repeating XDES pages every 16,384 pages after that (page 16384, 32768, …). The FSP_HDR and XDES page structure is completely identical, with the exception that the FSP header structure is zero-filled on XDES pages, but populated on FSP_HDR pages.

The basic structure of FSP_HDR and XDES pages is: FIL header, FSP header, an array of 256 XDES entries, empty (unused) space, and FIL trailer.

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, SPECIALIZED_CLASSES

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, #checksum_crc32, #checksum_crc32?, #checksum_innodb, #checksum_innodb?, #checksum_invalid?, #checksum_trailer, #checksum_type, #checksum_valid?, #corrupt?, #cursor, #each_page_body_byte_as_uint8, #each_page_header_byte_as_uint8, #fil_header, #fil_trailer, handle, #in_doublewrite_buffer?, #initialize, #inspect, #lsn, #lsn_low32_header, #lsn_low32_trailer, maybe_undefined, #misplaced?, #misplaced_offset?, #misplaced_space?, #name, #next, #offset, parse, #pos_fil_header, #pos_fil_trailer, #pos_page_body, #pos_partial_page_header, #prev, #size, #size_fil_header, #size_fil_trailer, #size_page_body, #size_partial_page_header, #space_id, #torn?, #type

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.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 44

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))

  {
    :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



22
23
24
25
26
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 22

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

Instance Method Details

#dumpObject

Dump the contents of a page for debugging purposes.



181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 181

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.



125
126
127
128
129
130
131
132
133
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 125

def each_list
  unless block_given?
    return enum_for(:each_list)
  end

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

#each_region {|{ :offset => pos_fsp_header, :length => size_fsp_header, :name => :fsp_header, :info => "FSP Header", }| ... } ⇒ Object

Yields:



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 151

def each_region
  unless block_given?
    return enum_for(:each_region)
  end

  super do |region|
    yield region
  end

  yield({
    :offset => pos_fsp_header,
    :length => size_fsp_header,
    :name => :fsp_header,
    :info => "FSP Header",
  })

  each_xdes do |xdes|
    state = xdes.state || "unused"
    yield({
      :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).



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

def each_xdes
  unless block_given?
    return enum_for(:each_xdes)
  end

  cursor(pos_xdes_array).name("xdes_array") do |c|
    entries_in_xdes_array.times do |n|
      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.



79
80
81
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 79

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.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 93

def fsp_header
  @fsp_header ||= cursor(pos_fsp_header).name("fsp") do |c|
    {
      :space_id           => c.name("space_id") { c.get_uint32 },
      :unused             => c.name("unused") { c.get_uint32 },
      :size               => c.name("size") { c.get_uint32 },
      :free_limit         => c.name("free_limit") { c.get_uint32 },
      :flags              => c.name("flags") {
        self.class.decode_flags(c.get_uint32)
      },
      :frag_n_used        => c.name("frag_n_used") { c.get_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.get_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.



62
63
64
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 62

def pos_fsp_header
  pos_page_body
end

#pos_xdes_arrayObject

The XDES entry array immediately follows the FSP header.



73
74
75
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 73

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.



68
69
70
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 68

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

#size_xdes_arrayObject



87
88
89
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 87

def size_xdes_array
  entries_in_xdes_array * size_xdes_entry
end

#size_xdes_entryObject



83
84
85
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 83

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