Class: Innodb::Page::FspHdrXdes
- Inherits:
-
Innodb::Page
- Object
- Innodb::Page
- Innodb::Page::FspHdrXdes
- 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_ADJUST =
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, SPECIALIZED_CLASSES
Instance Attribute Summary
Attributes inherited from Innodb::Page
Class Method Summary collapse
-
.decode_flags(flags) ⇒ Object
Decode the "flags" field in the FSP header, returning a hash of useful decoded flags.
-
.read_bits_at_offset(data, bits, offset) ⇒ Object
Read a given number of bits from an integer at a specific bit offset.
Instance Method Summary collapse
-
#dump ⇒ Object
Dump the contents of a page for debugging purposes.
-
#each_list ⇒ Object
Iterate through all lists in the file space.
-
#each_xdes ⇒ Object
Iterate through all XDES entries in order.
-
#entries_in_xdes_array ⇒ Object
The number of entries in the XDES array.
-
#fsp_header ⇒ Object
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.
-
#pos_fsp_header ⇒ Object
The FSP header immediately follows the FIL header.
-
#pos_xdes_array ⇒ Object
The XDES entry array immediately follows the FSP header.
-
#size_fsp_header ⇒ Object
The FSP header contains six 32-bit integers, one 64-bit integer, and 5 list base nodes.
Methods inherited from Innodb::Page
#calculate_checksum, #checksum, #corrupt?, #cursor, #data, #fil_header, handle, #initialize, #inspect, #lsn, maybe_undefined, #next, #offset, parse, #pos_fil_header, #pos_fil_trailer, #pos_page_body, #prev, #size, #size_fil_header, #size_fil_trailer, #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 decoded flags. Unfortunately, InnoDB has a fairly weird and broken implementation of these flags. The flags are:
Offset Size Description 0 1 Page Format (redundant, compact). This is unfortunately coerced to 0 if it is "compact" and no other flags are set, making it useless to innodb_ruby. 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 Table Format (Antelope, Barracuda). This was supposed to reserve 6 bits, but due to a bug in InnoDB only actually reserved 1 bit.
41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 41 def self.decode_flags(flags) # The page size for compressed pages is stored at bit offset 1 and consumes # 4 bits. Value 0 means the page is not compressed. page_size = read_bits_at_offset(flags, 4, 1) { :compressed => page_size == 0 ? false : true, :page_size => page_size == 0 ? Innodb::Space::DEFAULT_PAGE_SIZE : (1 << (FLAGS_PAGE_SIZE_ADJUST + page_size)), :value => flags, } end |
.read_bits_at_offset(data, bits, offset) ⇒ Object
Read a given number of bits from an integer at a specific bit offset. The value returned is 0-based so does not need further shifting or adjustment.
21 22 23 |
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 21 def self.read_bits_at_offset(data, bits, offset) ((data & (((1 << bits) - 1) << offset)) >> offset) end |
Instance Method Details
#dump ⇒ Object
Dump the contents of a page for debugging purposes.
137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 137 def dump super puts "fsp header:" pp fsp_header puts puts "xdes entries:" each_xdes do |xdes| pp xdes end puts end |
#each_list ⇒ Object
Iterate through all lists in the file space.
110 111 112 113 114 115 116 117 118 |
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 110 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_xdes ⇒ Object
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).
124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 124 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_array ⇒ Object
The number of entries in the XDES array. Defined as page size divided by extent size.
72 73 74 |
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 72 def entries_in_xdes_array size / space.pages_per_extent end |
#fsp_header ⇒ Object
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.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 78 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_header ⇒ Object
The FSP header immediately follows the FIL header.
55 56 57 |
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 55 def pos_fsp_header pos_fil_header + size_fil_header end |
#pos_xdes_array ⇒ Object
The XDES entry array immediately follows the FSP header.
66 67 68 |
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 66 def pos_xdes_array pos_fsp_header + size_fsp_header end |
#size_fsp_header ⇒ Object
The FSP header contains six 32-bit integers, one 64-bit integer, and 5 list base nodes.
61 62 63 |
# File 'lib/innodb/page/fsp_hdr_xdes.rb', line 61 def size_fsp_header ((4 * 6) + (1 * 8) + (5 * Innodb::List::BASE_NODE_SIZE)) end |