Question

I have DB InnoDb innodb_db_1. I have turned on innodb_file_per_table.

If I go to var/lib/mysql/innodb_db_1/ I will find files table_name.ibd, table_name.frm, db.opt.

Now, I'm trying to copy these files to another DB for example to innodb_db_2(var/lib/mysql/innodb_db_2/) but nothing happened.

But if my DB will be MyIsam, I can copy in such way and everything be ok.

What suggestions to move the DB by copying the file of InnoDb DB?

Was it helpful?

Solution

Even when you use file-per-table, the tables keep some of their data and metadata in /var/lib/mysql/ibdata1. So you can't just move .ibd files to a new MySQL instance.

You'll have to backup and restore your database. You can use:

  • mysqldump, included with MySQL, reliable but slow.

  • mydumper, a community contributed substitute for mysqldump, this supports compression and parallel execution and other neat features.

  • Percona XtraBackup, which is free and performs high-speed physical backups of InnoDB (and also supports other storage engines). This is recommended to minimize interruption to your live operations, and also if your database is large.


Re your comment:

No, you cannot just copy .ibd files. You cannot turn off the requirement for ibdata1. This file includes, among other things, a data dictionary which you can think of like a table of contents for a book. It tells InnoDB what tables you have, and which physical file they reside in.

If you just move a .ibd file into another MySQL instance, this does not add it to that instance's data dictionary. So InnoDB has no idea to look in the new file, or which logical table it goes with.

If you want a workaround, you could ALTER TABLE mytable ENGINE=MyISAM, move that file and its .frm to another instance, and then ALTER TABLE mytable ENGINE=InnoDB to change it back. Remember to FLUSH TABLES WITH READ LOCK before you move MyISAM files.

But these steps are not for beginners. It would be a lot safer for you to use the backup & restore method unless you know what you're doing. I'm trying to save you some grief.

OTHER TIPS

There is an easy procedure to move the whole Mysql InnoDB from pc A to pc B.

The conditions to perform the procedure are:

  1. You need to have innodb_file_per_table option set
  2. You need to be able to make a shutdown of the database

In my case i had to move whole 150Gb MySql database (the biggest table had aprox. 60Gb). Making sqldumps and loading them back was not an option (too slow).

So what I did was I made a "cold backup" of the mysql database (mysql doc) and then simply move files to another computer.

The steps to make after moving the databse are described here dba stackexchange.

I am writing this, because (assuming you are able to follow mentioned conditions) this is by far the fastest (and probalby the easiest) method to move a (large) MySql InnoDb and nobody mentioned it yet.

You can copy MyISAM tables all day long (safely, as long as they are flushed and locked or the server is stopped) but you can't do this with InnoDB, because the two storage engines handle tables and tablespaces very differently.

  • MyISAM automatically discovers tables by iterating the files in the directory named for the database.

  • InnoDB has an internal data dictionary stored in the system tablespace (ibdata1). Not only do the tables have to be consistent, there are identifiers in the .ibd files that must match what the data dictionary has stored internally.

Prior to MySQL 5.6, with the introduction of transportable tablespaces, this wasn't a supported operation. If you are using MySQL 5.6, the link provides you with information on how this works.

The alternatives:

  • use mysqldump [options] database_name > dumpfile.sql without the --databases option, which will dump the tables in the specified database but will omit any DATABASE commands (DROP DATABASE, CREATE DATABASE and USE), some or all of which, based on the combination of options specified, are normally added to the dump file. You can then import this with mysql [options] < dumpfile.sql.

  • CREATE TABLE db2.t1 LIKE db1.t1; INSERT INTO db2.t1 SELECT * FROM db1.t1; (for each table; you'll have to add any foreign key constraints back in)

  • ALTER TABLE on each table, changing it to MyISAM, then flushing and locking the tables with FLUSH TABLES WITH READ LOCK;, copying them over, then altering everything back to InnoDB. Not the greatest idea, since you'll lose all foreign key declarations and have to add them back on the original tables, but it is an alternative.

As far as I know, "hot copying" table files is a very bad idea (I've done it two times, and only made it work with MyISAM tables, and i did it only because I had no other choice).

My personal recomendation is: Use mysqldump. On your shell:

mysqldump -h yourHost -u yourUser -pYourPassword yourDatabase yourTable > dumpFile.sql

To copy the data from a dump file to another database, on your shell:

mysql -h yourHost -u yourUser -pYourPassword yourNewDatabase < dumpFile.sql

Check: mysqldump — A Database Backup Program.


If you insist on copying InnoDB files by hand, please read this: Backing Up and Recovering an InnoDB Database

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top