[philiptellis] /bb|[^b]{2}/
Never stop Grokking


Monday, March 22, 2010

InnoDB's tablespace ids and Partitions

There are times when what you have is a partially running database and a bunch of backup innodb tablespace files (the .ibd files). If you're using innodb_file_per_table, then you have a separate .ibd file for each InnoDB table.

Now, you have your running database with a bunch of tables, and you want to replace some of them with the backup .ibd files. According to the MySQL docs, you'd do this:
  1. ALTER TABLE foo DISCARD TABLESPACE; (this deletes the current .ibd file)
  2. copy the old .ibd file into your database directory
  3. ALTER TABLE foo IMPORT TABLESPACE;
Assuming your .ibd file was from the same database and you did not drop the table and recreate it sometime between when you made the backup .ibd and now, this should work. Except... if you use partitions. If your table foo uses partitions, ie, its create statement was something like this:
CREATE TABLE foo (
   ...
) PARTITION BY ... (
   PARTITION p0 ...,
);
In this case, you cannot discard the tablespace, and the first alter command throws an error:
mysql> ALTER TABLE foo DISCARD TABLESPACE;

ERROR 1031 (HY000): Table storage engine for 'foo' doesn't have this option
I have not investigated if there are workarounds for this, but I do have a little more information on what's happening. Remember that each .ibd file is a tablespace. For a partitioned table, there are multiple .ibd files, one for each partition. The table's files look like this:
foo.frm
foo.par
foo#P#p0.ibd
foo#P#p1.ibd
...
Where p0, p1, etc. are the partition names that you specified in the create statement. Each partition is a different tablespace and has its own tablespace id. When you create an InnoDB table without partitioning, the internal tablespace id counter is incremented by 1. When you create an InnoDB table with paritions, the internal tablespace id counter is incremented by the number of partitions. The actual tablespace id is stored in each partition's .ibd file somewhere within the first 100 bytes. I have not attempted to find out where exactly though.

4 comments :

Morgan
March 22, 2010 10:09 AM

I believe the space_id is a 32-bit int, so there's not too much risk of running out.

XtraDB can import .ibd files from other servers. See:
http://www.mysqlperformanceblog.com/2009/07/31/copying-innodb-tables-between-servers/

I haven't tried this with partitioning.

Anonymous
March 25, 2010 2:58 AM

Thanks. This info. solved one of my problems related to table space in MySQL. It was really a good effort.

-Abhijit

Mattias
March 28, 2010 4:19 PM

Please report this as a bug, so I can take a deeper look into how to fix this in the partitioning code.

Regards
Mattias Jonsson, MySQL partitioning developer

Blues
March 28, 2010 11:42 PM

bug filed: http://bugs.mysql.com/bug.php?id=52422

Post a Comment

...===...