Skip to content

Commit

Permalink
Add support for multiple data file system tablespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremycole committed Oct 3, 2014
1 parent a05711e commit d8c5a95
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 24 deletions.
4 changes: 2 additions & 2 deletions bin/innodb_space
Original file line number Diff line number Diff line change
Expand Up @@ -1309,9 +1309,9 @@ getopt.each do |opt, arg|
when "--trace"
@options.trace += 1
when "--system-space-file"
@options.system_space_file = arg
@options.system_space_file = arg.split(",")
when "--space-file"
@options.space_file = arg
@options.space_file = arg.split(",")
when "--table-name"
@options.table_name = arg
when "--index-name"
Expand Down
62 changes: 45 additions & 17 deletions lib/innodb/space.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,39 @@ class Innodb::Space
7 => :SYS,
}

class DataFile
attr_reader :file
attr_reader :size
attr_reader :offset

def initialize(filename, offset)
@file = File.open(filename)
@size = @file.stat.size
@offset = offset
end

def name
prefix = ""
if File.extname(file.path) == ".ibd"
prefix = File.basename(File.dirname(file.path)) + "/"
end

prefix + File.basename(file.path)
end
end

# Open a space file, optionally providing the page size to use. Pages
# that aren't 16 KiB may not be supported well.
def initialize(file)
@file = File.open(file)
@size = @file.stat.size
def initialize(filenames)
filenames = [filenames] unless filenames.is_a?(Array)

@data_files = []
@size = 0
filenames.each do |filename|
file = DataFile.new(filename, @size)
@size += file.size
@data_files << file
end

@system_page_size = fsp_flags[:system_page_size]
@page_size = fsp_flags[:page_size]
Expand Down Expand Up @@ -58,14 +86,7 @@ def initialize(file)
# to do anything which could instantiate a BufferCursor so that we can use
# this method in cursor initialization.
def name
return @name if @name

prefix = ""
if File.extname(@file.path) == ".ibd"
prefix = File.basename(File.dirname(@file.path)) + "/"
end

@name = prefix + File.basename(@file.path)
@name ||= @data_files.map { |f| f.name }.join(",")
end

def inspect
Expand Down Expand Up @@ -184,18 +205,25 @@ def xdes_for_page(page_number)
xdes_array[xdes_entry_for_page(page_number)]
end

def data_file_for_offset(offset)
@data_files.each do |file|
return file if offset < file.size
offset -= file.size
end
nil
end

# Get the raw byte buffer of size bytes at offset in the file.
def read_at_offset(offset, size)
@file.seek(offset)
@file.read(size)
return nil unless offset < @size && (offset + size) <= @size
data_file = data_file_for_offset(offset)
data_file.file.seek(offset - data_file.offset)
data_file.file.read(size)
end

# Get the raw byte buffer for a specific page by page number.
def page_data(page_number)
offset = page_number.to_i * page_size
return nil unless offset < @size
return nil unless (offset + page_size) <= @size
read_at_offset(offset, page_size)
read_at_offset(page_number * page_size, page_size)
end

# Get an Innodb::Page object for a specific page by page number.
Expand Down
24 changes: 19 additions & 5 deletions lib/innodb/system.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,28 @@ class Innodb::System
# The space ID of the system space, always 0.
SYSTEM_SPACE_ID = 0

def initialize(system_space_file)
def initialize(arg)
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
if data_filenames.empty?
raise "Couldn't find any ibdata files in #{arg}"
end
else
data_filenames = [arg]
end
end

@spaces = {}
@orphans = []
@config = {
:datadir => File.dirname(system_space_file),
:datadir => File.dirname(data_filenames.first),
}

add_space_file(system_space_file)
add_space_file(data_filenames)

@data_dictionary = Innodb::DataDictionary.new(system_space)
end
Expand All @@ -45,8 +59,8 @@ def add_space(space)
end

# Add a space by filename.
def add_space_file(space_file)
space = Innodb::Space.new(space_file)
def add_space_file(space_filenames)
space = Innodb::Space.new(space_filenames)
space.innodb_system = self
add_space(space)
end
Expand Down

0 comments on commit d8c5a95

Please sign in to comment.