class Innodb::System

Constants

SYSTEM_SPACE_ID

The space ID of the system space, always 0.

Attributes

config[R]

A hash of configuration options by configuration key.

data_dictionary[R]

The Innodb::DataDictionary for this system.

orphans[R]

Array of space names for which a space file was not found.

spaces[R]

A hash of spaces by space ID.

Public Class Methods

new(arg, data_directory: nil) click to toggle source
# File lib/innodb/system.rb, line 22
def initialize(arg, data_directory: nil)
  if arg.is_a?(Array) && arg.size > 1
    data_filenames = arg
  else
    arg = arg.first if arg.is_a?(Array)
    if File.directory?(arg)
      data_filenames = Dir.glob("#{arg}/ibdata?").sort
      raise "Couldn't find any ibdata files in #{arg}" if data_filenames.empty?
    else
      data_filenames = [arg]
    end
  end

  @spaces = {}
  @orphans = []
  @config = {
    data_directory: data_directory || File.dirname(data_filenames.first),
  }

  add_space_file(data_filenames)

  @data_dictionary = Innodb::DataDictionary.new(system_space)
end

Public Instance Methods

add_space(space) click to toggle source

Add an already-constructed Innodb::Space object.

# File lib/innodb/system.rb, line 52
def add_space(space)
  raise "Object was not an Innodb::Space" unless space.is_a?(Innodb::Space)

  spaces[space.space_id.to_i] = space
end
add_space_file(space_filenames) click to toggle source

Add a space by filename.

# File lib/innodb/system.rb, line 59
def add_space_file(space_filenames)
  space = Innodb::Space.new(space_filenames)
  space.innodb_system = self
  add_space(space)
end
add_space_orphan(space_file) click to toggle source

Add an orphaned space.

# File lib/innodb/system.rb, line 66
def add_space_orphan(space_file)
  orphans << space_file
end
add_table(table_name) click to toggle source

Add a space by table name, constructing an appropriate filename from the provided table name.

# File lib/innodb/system.rb, line 72
def add_table(table_name)
  space_file = "%s/%s.ibd" % [config[:data_directory], table_name]
  if File.exist?(space_file)
    add_space_file(space_file)
  else
    add_space_orphan(table_name)
  end
end
clustered_index_by_table_id(table_id) click to toggle source

Return the clustered index given a table ID.

# File lib/innodb/system.rb, line 197
def clustered_index_by_table_id(table_id)
  table_name = table_name_by_id(table_id)
  return unless table_name

  index_by_name(table_name, clustered_index_by_table_name(table_name))
end
clustered_index_by_table_name(table_name) click to toggle source

Return the clustered index name given a table name.

# File lib/innodb/system.rb, line 171
def clustered_index_by_table_name(table_name)
  data_dictionary.clustered_index_name_by_table_name(table_name)
end
each_column_name_by_table_name(table_name) { |record| ... } click to toggle source

Iterate through all column names by table name.

# File lib/innodb/system.rb, line 127
def each_column_name_by_table_name(table_name)
  return enum_for(:each_column_name_by_table_name, table_name) unless block_given?

  data_dictionary.each_column_by_table_name(table_name) do |record|
    yield record["NAME"]
  end

  nil
end
each_index_field_name_by_index_name(table_name, index_name) { |record| ... } click to toggle source

Iterate through all field names in a given index by table name and index name.

# File lib/innodb/system.rb, line 150
def each_index_field_name_by_index_name(table_name, index_name)
  return enum_for(:each_index_field_name_by_index_name, table_name, index_name) unless block_given?

  data_dictionary.each_field_by_index_name(table_name, index_name) do |record|
    yield record["COL_NAME"]
  end

  nil
end
each_index_name_by_table_name(table_name) { |record| ... } click to toggle source

Iterate through all index names by table name.

# File lib/innodb/system.rb, line 138
def each_index_name_by_table_name(table_name)
  return enum_for(:each_index_name_by_table_name, table_name) unless block_given?

  data_dictionary.each_index_by_table_name(table_name) do |record|
    yield record["NAME"]
  end

  nil
end
each_orphan(&block) click to toggle source

Iterate throught all orphaned spaces.

# File lib/innodb/system.rb, line 118
def each_orphan(&block)
  return enum_for(:each_orphan) unless block_given?

  orphans.each(&block)

  nil
end
each_table_name() { |record| ... } click to toggle source

Iterate through all table names.

# File lib/innodb/system.rb, line 107
def each_table_name
  return enum_for(:each_table_name) unless block_given?

  data_dictionary.each_table do |record|
    yield record["NAME"]
  end

  nil
end
history() click to toggle source
# File lib/innodb/system.rb, line 204
def history
  Innodb::History.new(self)
end
index_by_name(table_name, index_name) click to toggle source

Return an Innodb::Index object given a table name and index name.

# File lib/innodb/system.rb, line 188
def index_by_name(table_name, index_name)
  index_record = data_dictionary.index_by_name(table_name, index_name)

  index_space = space(index_record["SPACE"])
  describer = data_dictionary.record_describer_by_index_name(table_name, index_name)
  index_space.index(index_record["PAGE_NO"], describer)
end
index_name_by_id(index_id) click to toggle source

Return the index name given an index ID.

# File lib/innodb/system.rb, line 166
def index_name_by_id(index_id)
  data_dictionary.index_by_id(index_id).fetch("NAME", nil)
end
space(space_id) click to toggle source

Return an Innodb::Space object for a given space ID, looking up and adding the single-table space if necessary.

# File lib/innodb/system.rb, line 83
def space(space_id)
  return spaces[space_id] if spaces[space_id]

  unless (table_record = data_dictionary.table_by_space_id(space_id))
    raise "Table with space ID #{space_id} not found"
  end

  add_table(table_record["NAME"])

  spaces[space_id]
end
space_by_table_name(table_name) click to toggle source

Return an Innodb::Space object by table name.

# File lib/innodb/system.rb, line 96
def space_by_table_name(table_name)
  unless (table_record = data_dictionary.table_by_name(table_name))
    raise "Table #{table_name} not found"
  end

  return if table_record["SPACE"].zero?

  space(table_record["SPACE"])
end
system_space() click to toggle source

A helper to get the system space.

# File lib/innodb/system.rb, line 47
def system_space
  spaces[SYSTEM_SPACE_ID]
end
table_and_index_name_by_id(index_id) click to toggle source

Return an array of the table name and index name given an index ID.

# File lib/innodb/system.rb, line 176
def table_and_index_name_by_id(index_id)
  if (dd_index = data_dictionary.data_dictionary_index_ids[index_id])
    # This is a data dictionary index, which won't be found in the data
    # dictionary itself.
    [dd_index[:table], dd_index[:index]]
  elsif (index_record = data_dictionary.index_by_id(index_id))
    # This is a system or user index.
    [table_name_by_id(index_record["TABLE_ID"]), index_record["NAME"]]
  end
end
table_name_by_id(table_id) click to toggle source

Return the table name given a table ID.

# File lib/innodb/system.rb, line 161
def table_name_by_id(table_id)
  data_dictionary.table_by_id(table_id).fetch("NAME", nil)
end