暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

通过MySQL表空间ibd文件,复制或迁移InnoDB表的数据

162
要迁移或者复制MySQL某张表的数据,通常建议是使用mysqldump。
那有没有其他办法呢?
今天就来介绍另外一种方法:
通过表空间文件,来迁移或者复制某张MySQL表的数据。

前提条件

如果真的要通过表空间导入其他实例的数据,首先需要满足这些条件:

1 必须开启独立表空间,也就是innodb_file_per_table 必须开启;

2 表空间的页面大小必须与目标 MySQL 服务器实例的页面大小匹配,也就是页大小配置参数innodb_page_size需要相等;

3 如果表有外键关系,在导入之前必须禁用foreign_key_checks,并且应该在同一逻辑时间点导出所有与外键相关的表,所以,建议在导出期间,停止更新有外键约束的相关表;

4 当从另一个MySQL服务器实例导入表时,两个MySQL服务器实例必须具有相同的General Availability (GA)状态,并且必须是相同的版本。否则,必须在导入表的同一个MySQL服务器实例上创建表;

5 如果表是通过在CREATE table语句中指定DATA directory子句在外部目录中创建的,那么在目标实例上替换的表必须用相同的DATA directory子句定义;

6 如果在表定义中没有显式定义ROW_FORMAT选项,或者使用了ROW_FORMAT=DEFAULT,则源实例和目标实例上的innodb_default_row_format设置必须相同。


步骤

建议采用下面的步骤:

1 在源实例上查看表结构;

2 在目标实例创建系统结构的表;

3 在目标实例上,丢弃刚刚创建的表的表空间;

4 在源实例上,把表的更新刷新到磁盘,FLUSH TABLES xxx FOR EXPORT;

5 把原实例的数据文件和元数据文件复制到目标实例对应库的数据目录下。这里需要把属组改成MySQL;

6 在源实例上,释放锁,执行的是unlock tables;

7 在目标实例导入表空间,执行ALTER TABLE xxx IMPORT TABLESPACE;

8 确定数据是否导入成功。


实验

感兴趣的,也可以在测试环境做一下这个实验。

在源实例创建测试表,并写入测试数据:

    use martin
    create table importing_table_t1(
        id INT PRIMARY KEY AUTO_INCREMENT,
        name varchar(10)
    ) engine = innodb;
    insert into importing_table_t1(name) values ('a'),('b');


    实验正式开始。

    在源实例上查看表结构:

      show create table importing_table_t1;


      在目标实例上,创建一张与要导入表具有相同表结构定义的表:

        use martin
        create table importing_table_t1(
            id INT PRIMARY KEY AUTO_INCREMENT,
            name varchar(10)
        ) engine = innodb;

        在目标实例上,丢弃刚刚创建的表的表空间:

          ALTER TABLE importing_table_t1 DISCARD TABLESPACE;


          在源实例上,运行(这里要注意,这一步操作会导致这张表无法修改):

            use  martin
            FLUSH TABLES importing_table_t1 FOR EXPORT;

            这样,能确保对表的更新刷新到磁盘,以便服务器运行时创建二进制表副本。


            并且会生成一个.cfg 的元数据文件,这个文件包含在导入操作中用于模式验证的元数据。


            并且FLUSH TABLES ... FOR EXPORT运行期间,执行的连接必须保持打开状态,否则.cfg文件将被删除。


            在源实例,复制数据文件和元数据文件到目标实例:

              cd /data/mysql/data/martin
              scp importing_table_t1.{ibd,cfg} xxx:/data/mysql/data/martin

              传到目标实例的数据目录之后,需要确定属组是不是mysql,不是的话需要执行下面命令修改属组:

                chown mysql.mysql importing_table_t1.*


                在源实例上,释放锁:

                  use martin
                  unlock tables;

                  这个操作也会把.cfg文件删除。


                  我们到数据目录再来查看这张表的数据文件

                    ll |grep importing_table_t1

                    发现只剩下ibd文件了。


                    在目标实例导入表空间,执行:

                      use martin
                      ALTER TABLE importing_table_t1  IMPORT TABLESPACE;


                      确定数据是否导入,在目标实例执行:

                        select * from importing_table_t1;

                        这也是我们最开始在源实例写入的两条数据,说明数据完成了复制。


                        因为过程会涉及到锁表,所以在生产环境谨慎使用。


                        另外,想系统学习DBA的,可以关注下小编的视频课程:

                        https://class.imooc.com/sale/dba

                        今晚(6月5日)20:00,618活动正式开启,全年最低价!

                        考虑购买的可以私聊我(mating3306)领取专属优惠码。

                        文章转载自MySQL数据库联盟,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                        评论