mysql通过表空间来恢复或者传递数据

mysql的备份工具通常有 mysqldump ,mysqlpump(5.7后新特性)等备份工具,这里我们可以尝试使用表空间进行传递

方式是:拷贝数据文件+拷贝表空间   对应innodb引擎就是 ibd文件和cfg文件

执行此种方式的要求

(1)需要使用独立表空间,开启innodb_file_per_table参数;
(2)在做表导出时,该表只允许读不允许写;
(3)导入导出的数据data page size必须一样;
(4)在 MySQL 5.7.4 之前的版本是不能对分区表做分区迁移;
(5)使用外键的表,需要使用 set foreign_key_check=0强制忽略外键,否则不支持表空间的导入导出,分布表不支持外键表空间的导入导出;

 

下面举个例子进行说明

1 普通表空间的传递

准备两个mysql,源+目标,同时进行建表命令,一个我们称呼为源mysql,一个称呼为目标mysql

create table first(id int,name char(16));

在源mysql中插入数据

insert into first values(1,'ni'),(2,'wo'),(3,'ta');

在目标mysql上面释放表空间

alter table first discard tablespace;  #相当于删除了first.ibd文件,留下了 first.frm
此时你可以对 frm 文件操作,例如:rename table,drop table ,但是不能对 ibd 文件操作,比如:dml
验证结果:
select * from first;
ERROR 1814 (HY000): Tablespace has been discarded for table 'first'

 在源mysql上面创建.cfg元数据文件,注意,不要关闭当前窗口,否则消失

flush tables first for export;  #此时,源MySQL有了first.cfg文件,
验证情况:
insert into first values(10,'hehe'); DML 操作是阻塞的

ERROR 1099 (HY000): Table 'first' was locked with a READ lock and can't be updated

复制first.cfg文件和first.ibd文件到目标mysql

cp  源mysql路径/first.{cfg,ibd}  目标mysql/
修改权限
chown mysql.mysql *

源mysql释放锁

UNLOCK TABLES;

目标mysql导入表空间

alter table first  import tablespace;

目标mysql查看结果

select * from first;

 2 分区表空间传递(mysql5.7.4之后的版本)

接替上一篇博客建立的分区表 test_range_partition 我们来做分区表的迁移

在目标服务器上面建立database和表test_range_partition

mysql> CREATE TABLE test_range_partition(
    ->     id INT auto_increment,
    ->     createdate DATETIME,
    ->     primary key (id,createdate)
    -> ) 
    -> PARTITION BY RANGE (TO_DAYS(createdate) ) (
    ->    PARTITION p201801 VALUES LESS THAN ( TO_DAYS('20180201') ),
    ->    PARTITION p201802 VALUES LESS THAN ( TO_DAYS('20180301') ),
    ->    PARTITION p201803 VALUES LESS THAN ( TO_DAYS('20180401') ),
    ->    PARTITION p201804 VALUES LESS THAN ( TO_DAYS('20180501') ),
    ->    PARTITION p201805 VALUES LESS THAN ( TO_DAYS('20180601') ),
    ->    PARTITION p201806 VALUES LESS THAN ( TO_DAYS('20180701') ),
    ->    PARTITION p201807 VALUES LESS THAN ( TO_DAYS('20180801') ),
    ->    PARTITION p201808 VALUES LESS THAN ( TO_DAYS('20180901') ),
    ->    PARTITION p201809 VALUES LESS THAN ( TO_DAYS('20181001') ),
    ->    PARTITION p201810 VALUES LESS THAN ( TO_DAYS('20181101') ),
    ->    PARTITION p201811 VALUES LESS THAN ( TO_DAYS('20181201') ),
    ->    PARTITION p201812 VALUES LESS THAN ( TO_DAYS('20190101') )
    -> );
Query OK, 0 rows affected (0.06 sec)

在目标服务器上面删除表的指定分区表空间

alter table test_range_partition discard partition p201802 tablespace;

查看

[root@localhost target]# ls
db.opt                              test_range_partition#P#p201805.ibd  test_range_partition#P#p201810.ibd
test_range_partition.frm            test_range_partition#P#p201806.ibd  test_range_partition#P#p201811.ibd
test_range_partition#P#p201801.ibd  test_range_partition#P#p201807.ibd  test_range_partition#P#p201812.ibd
test_range_partition#P#p201803.ibd  test_range_partition#P#p201808.ibd
test_range_partition#P#p201804.ibd  test_range_partition#P#p201809.ibd

源服务器上面导出表空间,并复制到目标服务器上面

mysql> flush tables test_range_partition for export;
Query OK, 0 rows affected (0.00 sec)

scp 源服务器ip/test_range_partition#P#p201802.{cfg,ibd} 目标服务器/

查看目标服务器的内容,并修改权限,否则导入的时候报错

[root@localhost target]# ls
db.opt                              test_range_partition#P#p201803.ibd  test_range_partition#P#p201808.ibd
test_range_partition.frm            test_range_partition#P#p201804.ibd  test_range_partition#P#p201809.ibd
test_range_partition#P#p201801.ibd  test_range_partition#P#p201805.ibd  test_range_partition#P#p201810.ibd
test_range_partition#P#p201802.cfg  test_range_partition#P#p201806.ibd  test_range_partition#P#p201811.ibd
test_range_partition#P#p201802.ibd  test_range_partition#P#p201807.ibd  test_range_partition#P#p201812.ibd

chown mysql.mysql *

源服务器释放锁

mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

目标服务器导入表空间

mysql> alter table test_range_partition import partition p201802 tablespace;  #这里报错是因为没有修改属主
ERROR 1812 (HY000): Tablespace is missing for table `target`.`test_range_partition`.
mysql> alter table test_range_partition import partition p201802 tablespace;
Query OK, 0 rows affected (0.02 sec)

mysql> select * from test_range_partition; #只有两个数据,是因为导入了一个分区表空间,可以尝试导入所有的表空间
+----+---------------------+
| id | createdate          |
+----+---------------------+
|  2 | 2018-02-05 00:00:00 |
|  3 | 2018-02-06 00:00:00 |
+----+---------------------+
2 rows in set (0.00 sec)

 

你可能感兴趣的:(mysql通过表空间来恢复或者传递数据)