#### 15.6.1.3 Importing InnoDB Tables

[]()[]()[]()

 This section describes how to import tables using the *Transportable Tablespaces* feature, which permits importing tables, partitioned tables, or individual table partitions that reside in file-per-table tablespaces. There are many reasons why you might want to import tables:

* To run reports on a non-production MySQL server instance to avoid placing extra load on a production server.

* To copy data to a new replica server.

* To restore a table from a backed-up tablespace file.

* As a faster way of moving data than importing a dump file, which requires reinserting data and rebuilding indexes.

* To move a data to a server with storage media that is better suited to your storage requirements. For example, you might move busy tables to an SSD device, or move large tables to a high-capacity HDD device.

 The *Transportable Tablespaces* feature is described under the following topics in this section:

* [Prerequisites](innodb-table-import.html#innodb-table-import-prerequsites)

* [Importing Tables](innodb-table-import.html#innodb-table-import-example)

* [Importing Partitioned Tables](innodb-table-import.html#innodb-table-import-partitioned-table)

* [Importing Table Partitions](innodb-table-import.html#innodb-table-import-partitions)

* [Limitations](innodb-table-import.html#innodb-table-import-limitations)

* [Usage Notes](innodb-table-import.html#innodb-table-import-usage-notes)

* [Internals](innodb-table-import.html#innodb-table-import-internals)

##### Prerequisites

* The [`innodb_file_per_table`](innodb-parameters.html#sysvar_innodb_file_per_table) variable must be enabled, which it is by default.

* The page size of the tablespace must match the page size of the destination MySQL server instance. `InnoDB` page size is defined by the [`innodb_page_size`](innodb-parameters.html#sysvar_innodb_page_size) variable, which is configured when initializing a MySQL server instance.

* If the table has a foreign key relationship, [`foreign_key_checks`](server-system-variables.html#sysvar_foreign_key_checks) must be disabled before executing `DISCARD TABLESPACE`. Also, you should export all foreign key related tables at the same logical point in time, as [`ALTER TABLE ... IMPORT TABLESPACE`](alter-table.html) does not enforce foreign key constraints on imported data. To do so, stop updating the related tables, commit all transactions, acquire shared locks on the tables, and perform the export operations.

* When importing a table from another MySQL server instance, both MySQL server instances must have General Availability (GA) status and must be the same version. Otherwise, the table must be created on the same MySQL server instance into which it is being imported.

* If the table was created in an external directory by specifying the `DATA DIRECTORY` clause in the [`CREATE TABLE`](create-table.html) statement, the table that you replace on the destination instance must be defined with the same `DATA DIRECTORY` clause. A schema mismatch error is reported if the clauses do not match. To determine if the source table was defined with a `DATA DIRECTORY` clause, use [`SHOW CREATE TABLE`](show-create-table.html) to view the table definition. For information about using the `DATA DIRECTORY` clause, see [Section 15.6.1.2, “Creating Tables Externally”](innodb-create-table-external.html).

* If a `ROW_FORMAT` option is not defined explicitly in the table definition or `ROW_FORMAT=DEFAULT` is used, the [`innodb_default_row_format`](innodb-parameters.html#sysvar_innodb_default_row_format) setting must be the same on the source and destination instances. Otherwise, a schema mismatch error is reported when you attempt the import operation. Use [`SHOW CREATE TABLE`](show-create-table.html) to check the table definition. Use [`SHOW VARIABLES`](show-variables.html) to check the [`innodb_default_row_format`](innodb-parameters.html#sysvar_innodb_default_row_format) setting. For related information, see [Defining the Row Format of a Table](innodb-row-format.html#innodb-row-format-defining).

##### Importing Tables

 This example demonstrates how to import a regular non-partitioned table that resides in a file-per-table tablespace.

1. On the destination instance, create a table with the same definition as the table you intend to import. (You can obtain the table definition using [`SHOW CREATE TABLE`](show-create-table.html) syntax.) If the table definition does not match, a schema mismatch error is reported when you attempt the import operation.

   ```
   mysql> USE test;
   mysql> CREATE TABLE t1 (c1 INT) ENGINE=INNODB;
   ```

2. On the destination instance, discard the tablespace of the table that you just created. (Before importing, you must discard the tablespace of the receiving table.)

   ```
   mysql> ALTER TABLE t1 DISCARD TABLESPACE;
   ```

3. On the source instance, run [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) to quiesce the table you intend to import. When a table is quiesced, only read-only transactions are permitted on the table.

   ```
   mysql> USE test;
   mysql> FLUSH TABLES t1 FOR EXPORT;
   ```

   [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) ensures that changes to the named table are flushed to disk so that a binary table copy can be made while the server is running. When [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) is run, `InnoDB` generates a `.cfg` metadata file in the schema directory of the table. The `.cfg` file contains metadata that is used for schema verification during the import operation.

   Note

    The connection executing [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) must remain open while the operation is running; otherwise, the `.cfg` file is removed as locks are released upon connection closure.

4. Copy the `.ibd` file and `.cfg` metadata file from the source instance to the destination instance. For example:

   ```
   $> scp /path/to/datadir/test/t1.{ibd,cfg} destination-server:/path/to/datadir/test
   ```

    The `.ibd` file and `.cfg` file must be copied before releasing the shared locks, as described in the next step.

   Note

    If you are importing a table from an encrypted tablespace, `InnoDB` generates a `.cfp` file in addition to a `.cfg` metadata file. The `.cfp` file must be copied to the destination instance together with the `.cfg` file. The `.cfp` file contains a transfer key and an encrypted tablespace key. On import, `InnoDB` uses the transfer key to decrypt the tablespace key. For related information, see [Section 15.13, “InnoDB Data-at-Rest Encryption”](innodb-data-encryption.html).

5. On the source instance, use [`UNLOCK TABLES`](lock-tables.html) to release the locks acquired by the [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) statement:

   ```
   mysql> USE test;
   mysql> UNLOCK TABLES;
   ```

    The [`UNLOCK TABLES`](lock-tables.html) operation also removes the `.cfg` file.

6. On the destination instance, import the tablespace:

   ```
   mysql> USE test;
   mysql> ALTER TABLE t1 IMPORT TABLESPACE;
   ```

##### Importing Partitioned Tables

 This example demonstrates how to import a partitioned table, where each table partition resides in a file-per-table tablespace.

1. On the destination instance, create a partitioned table with the same definition as the partitioned table that you want to import. (You can obtain the table definition using [`SHOW CREATE TABLE`](show-create-table.html) syntax.) If the table definition does not match, a schema mismatch error is reported when you attempt the import operation.

   ```
   mysql> USE test;
   mysql> CREATE TABLE t1 (i int) ENGINE = InnoDB PARTITION BY KEY (i) PARTITIONS 3;
   ```

    In the `/*`datadir`*/test` directory, there is a tablespace `.ibd` file for each of the three partitions.

   ```
   mysql> \! ls /path/to/datadir/test/
   t1#p#p0.ibd  t1#p#p1.ibd  t1#p#p2.ibd
   ```

2. On the destination instance, discard the tablespace for the partitioned table. (Before the import operation, you must discard the tablespace of the receiving table.)

   ```
   mysql> ALTER TABLE t1 DISCARD TABLESPACE;
   ```

    The three tablespace `.ibd` files of the partitioned table are discarded from the `/*`datadir`*/test` directory.

3. On the source instance, run [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) to quiesce the partitioned table that you intend to import. When a table is quiesced, only read-only transactions are permitted on the table.

   ```
   mysql> USE test;
   mysql> FLUSH TABLES t1 FOR EXPORT;
   ```

   [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) ensures that changes to the named table are flushed to disk so that binary table copy can be made while the server is running. When [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) is run, `InnoDB` generates `.cfg` metadata files in the schema directory of the table for each of the table's tablespace files.

   ```
   mysql> \! ls /path/to/datadir/test/
   t1#p#p0.ibd  t1#p#p1.ibd  t1#p#p2.ibd
   t1#p#p0.cfg  t1#p#p1.cfg  t1#p#p2.cfg
   ```

    The `.cfg` files contain metadata that is used for schema verification when importing the tablespace. [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) can only be run on the table, not on individual table partitions.

4. Copy the `.ibd` and `.cfg` files from the source instance schema directory to the destination instance schema directory. For example:

   ```
   $>scp /path/to/datadir/test/t1*.{ibd,cfg} destination-server:/path/to/datadir/test
   ```

    The `.ibd` and `.cfg` files must be copied before releasing the shared locks, as described in the next step.

   Note

    If you are importing a table from an encrypted tablespace, `InnoDB` generates a `.cfp` files in addition to a `.cfg` metadata files. The `.cfp` files must be copied to the destination instance together with the `.cfg` files. The `.cfp` files contain a transfer key and an encrypted tablespace key. On import, `InnoDB` uses the transfer key to decrypt the tablespace key. For related information, see [Section 15.13, “InnoDB Data-at-Rest Encryption”](innodb-data-encryption.html).

5. On the source instance, use [`UNLOCK TABLES`](lock-tables.html) to release the locks acquired by [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list):

   ```
   mysql> USE test;
   mysql> UNLOCK TABLES;
   ```

6. On the destination instance, import the tablespace of the partitioned table:

   ```
   mysql> USE test;
   mysql> ALTER TABLE t1 IMPORT TABLESPACE;
   ```

##### Importing Table Partitions

 This example demonstrates how to import individual table partitions, where each partition resides in a file-per-table tablespace file.

 In the following example, two partitions (`p2` and `p3`) of a four-partition table are imported.

1. On the destination instance, create a partitioned table with the same definition as the partitioned table that you want to import partitions from. (You can obtain the table definition using [`SHOW CREATE TABLE`](show-create-table.html) syntax.) If the table definition does not match, a schema mismatch error is reported when you attempt the import operation.

   ```
   mysql> USE test;
   mysql> CREATE TABLE t1 (i int) ENGINE = InnoDB PARTITION BY KEY (i) PARTITIONS 4;
   ```

    In the `/*`datadir`*/test` directory, there is a tablespace `.ibd` file for each of the four partitions.

   ```
   mysql> \! ls /path/to/datadir/test/
   t1#p#p0.ibd  t1#p#p1.ibd  t1#p#p2.ibd t1#p#p3.ibd
   ```

2. On the destination instance, discard the partitions that you intend to import from the source instance. (Before importing partitions, you must discard the corresponding partitions from the receiving partitioned table.)

   ```
   mysql> ALTER TABLE t1 DISCARD PARTITION p2, p3 TABLESPACE;
   ```

    The tablespace `.ibd` files for the two discarded partitions are removed from the `/*`datadir`*/test` directory on the destination instance, leaving the following files:

   ```
   mysql> \! ls /path/to/datadir/test/
   t1#p#p0.ibd  t1#p#p1.ibd
   ```

   Note

    When [`ALTER TABLE ... DISCARD PARTITION ... TABLESPACE`](alter-table.html) is run on subpartitioned tables, both partition and subpartition table names are permitted. When a partition name is specified, subpartitions of that partition are included in the operation.

3. On the source instance, run [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) to quiesce the partitioned table. When a table is quiesced, only read-only transactions are permitted on the table.

   ```
   mysql> USE test;
   mysql> FLUSH TABLES t1 FOR EXPORT;
   ```

   [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) ensures that changes to the named table are flushed to disk so that binary table copy can be made while the instance is running. When [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) is run, `InnoDB` generates a `.cfg` metadata file for each of the table's tablespace files in the schema directory of the table.

   ```
   mysql> \! ls /path/to/datadir/test/
   t1#p#p0.ibd  t1#p#p1.ibd  t1#p#p2.ibd t1#p#p3.ibd
   t1#p#p0.cfg  t1#p#p1.cfg  t1#p#p2.cfg t1#p#p3.cfg
   ```

    The `.cfg` files contain metadata that used for schema verification during the import operation. [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) can only be run on the table, not on individual table partitions.

4. Copy the `.ibd` and `.cfg` files for partition `p2` and partition `p3` from the source instance schema directory to the destination instance schema directory.

   ```
   $> scp t1#p#p2.ibd t1#p#p2.cfg t1#p#p3.ibd t1#p#p3.cfg destination-server:/path/to/datadir/test
   ```

    The `.ibd` and `.cfg` files must be copied before releasing the shared locks, as described in the next step.

   Note

    If you are importing partitions from an encrypted tablespace, `InnoDB` generates a `.cfp` files in addition to a `.cfg` metadata files. The `.cfp` files must be copied to the destination instance together with the `.cfg` files. The `.cfp` files contain a transfer key and an encrypted tablespace key. On import, `InnoDB` uses the transfer key to decrypt the tablespace key. For related information, see [Section 15.13, “InnoDB Data-at-Rest Encryption”](innodb-data-encryption.html).

5. On the source instance, use [`UNLOCK TABLES`](lock-tables.html) to release the locks acquired by [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list):

   ```
   mysql> USE test;
   mysql> UNLOCK TABLES;
   ```

6. On the destination instance, import table partitions `p2` and `p3`:

   ```
   mysql> USE test;
   mysql> ALTER TABLE t1 IMPORT PARTITION p2, p3 TABLESPACE;
   ```

   Note

    When [`ALTER TABLE ... IMPORT PARTITION ... TABLESPACE`](alter-table.html) is run on subpartitioned tables, both partition and subpartition table names are permitted. When a partition name is specified, subpartitions of that partition are included in the operation.

##### Limitations

* The *Transportable Tablespaces* feature is only supported for tables that reside in file-per-table tablespaces. It is not supported for the tables that reside in the system tablespace or general tablespaces. Tables in shared tablespaces cannot be quiesced.

* [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) is not supported on tables with a `FULLTEXT` index, as full-text search auxiliary tables cannot be flushed. After importing a table with a `FULLTEXT` index, run [`OPTIMIZE TABLE`](optimize-table.html) to rebuild the `FULLTEXT` indexes. Alternatively, drop `FULLTEXT` indexes before the export operation and recreate the indexes after importing the table on the destination instance.

* Due to a `.cfg` metadata file limitation, schema mismatches are not reported for partition type or partition definition differences when importing a partitioned table. Column differences are reported.

* Prior to MySQL 8.0.19, index key part sort order information is not stored to the `.cfg` metadata file used during a tablespace import operation. The index key part sort order is therefore assumed to be ascending, which is the default. As a result, records could be sorted in an unintended order if one table involved in the import operation is defined with a DESC index key part sort order and the other table is not. The workaround is to drop and recreate affected indexes. For information about index key part sort order, see [Section 13.1.15, “CREATE INDEX Statement”](create-index.html).

   The `.cfg` file format was updated in MySQL 8.0.19 to include index key part sort order information. The issue described above does not affect import operations between MySQL 8.0.19 server instances or higher.

##### Usage Notes

* [`ALTER TABLE ... IMPORT TABLESPACE`](alter-table.html) does not require a `.cfg` metadata file to import a table. However, metadata checks are not performed when importing without a `.cfg` file, and a warning similar to the following is issued:

  ```
  Message: InnoDB: IO Read error: (2, No such file or directory) Error opening '.\
  test\t.cfg', will attempt to import without schema verification
  1 row in set (0.00 sec)
  ```

   Importing a table without a `.cfg` metadata file should only be considered if no schema mismatches are expected. The ability to import without a `.cfg` file could be useful in crash recovery scenarios where metadata is not accessible.

* On Windows, `InnoDB` stores database, tablespace, and table names internally in lowercase. To avoid import problems on case-sensitive operating systems such as Linux and Unix, create all databases, tablespaces, and tables using lowercase names. A convenient way to ensure that names are created in lowercase is to set [`lower_case_table_names`](server-system-variables.html#sysvar_lower_case_table_names) to 1 before initializing the server. (It is prohibited to start the server with a [`lower_case_table_names`](server-system-variables.html#sysvar_lower_case_table_names) setting that is different from the setting used when the server was initialized.)

  ```
  [mysqld]
  lower_case_table_names=1
  ```

* When running [`ALTER TABLE ... DISCARD PARTITION ... TABLESPACE`](alter-table.html) and [`ALTER TABLE ... IMPORT PARTITION ... TABLESPACE`](alter-table.html) on subpartitioned tables, both partition and subpartition table names are permitted. When a partition name is specified, subpartitions of that partition are included in the operation.

##### Internals

 The following information describes internals and messages written to the error log during a table import procedure.

 When [`ALTER TABLE ... DISCARD TABLESPACE`](alter-table.html) is run on the destination instance:

* The table is locked in X mode.

* The tablespace is detached from the table.

 When [`FLUSH TABLES ... FOR EXPORT`](flush.html#flush-tables-for-export-with-list) is run on the source instance:

* The table being flushed for export is locked in shared mode.

* The purge coordinator thread is stopped.

* Dirty pages are synchronized to disk.

* Table metadata is written to the binary `.cfg` file.

 Expected error log messages for this operation:

```
[Note] InnoDB: Sync to disk of '"test"."t1"' started.
[Note] InnoDB: Stopping purge
[Note] InnoDB: Writing table metadata to './test/t1.cfg'
[Note] InnoDB: Table '"test"."t1"' flushed to disk
```

 When [`UNLOCK TABLES`](lock-tables.html) is run on the source instance:

* The binary `.cfg` file is deleted.

* The shared lock on the table or tables being imported is released and the purge coordinator thread is restarted.

 Expected error log messages for this operation:

```
[Note] InnoDB: Deleting the meta-data file './test/t1.cfg'
[Note] InnoDB: Resuming purge
```

 When [`ALTER TABLE ... IMPORT TABLESPACE`](alter-table.html) is run on the destination instance, the import algorithm performs the following operations for each tablespace being imported:

* Each tablespace page is checked for corruption.

* The space ID and log sequence numbers (LSNs) on each page are updated.

* Flags are validated and LSN updated for the header page.

* Btree pages are updated.

* The page state is set to dirty so that it is written to disk.

 Expected error log messages for this operation:

```
[Note] InnoDB: Importing tablespace for table 'test/t1' that was exported
from host 'host_name'
[Note] InnoDB: Phase I - Update all pages
[Note] InnoDB: Sync to disk
[Note] InnoDB: Sync to disk - done!
[Note] InnoDB: Phase III - Flush changes to disk
[Note] InnoDB: Phase IV - Flush complete
```

Note

 You may also receive a warning that a tablespace is discarded (if you discarded the tablespace for the destination table) and a message stating that statistics could not be calculated due to a missing `.ibd` file:

```
[Warning] InnoDB: Table "test"."t1" tablespace is set as discarded.
7f34d9a37700 InnoDB: cannot calculate statistics for table
"test"."t1" because the .ibd file is missing. For help, please refer to
http://dev.mysql.com/doc/refman/8.0/en/innodb-troubleshooting.html
```

