zoukankan      html  css  js  c++  java
  • mysql通过表空间来恢复或者传递数据

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

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

    .cfg: 该文件存储了表的数据字典信息

    执行此种方式的要求

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

    使用这种的方式的几个限制

    源库和目标库版本一致
    只适用于 innodb 引擎表
    源库执行 flush tables t for export 时,该表会不可写

     对于移动一个大表我们来思考一下

    使用mysqldump+source的方式:考虑逻辑备份的语句是不是很多,对于一个大表,如果用了很长时间的话,操作频繁,耗时也长
    
    使用select into outfile + load infile 会快一点,但是在生产上主从的环境,要知道主库会将所有的数据当作一个事务执行,只有把数据全部成功插入后,才会将 binlog 复制到从库,
    这样会造成从库严重延迟,而且生成的单个 binlog 大小严重超标,在磁盘空间不足时可能会把磁盘占满。
    使用xtraback增量备份的话,如何之前一直有备份最好,合并就行,临时使用的话,io消耗比较大,备份的文件大小也比mysqldump的大

    使用移动表空间,消耗的时间较短,但是要考虑锁表的问题,并且目标数据库需要提前建库建表

    下面举个例子进行说明

    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;

     注意:如果是加密的表空间,传递的文件就是 .cfp  .cfg  .ibd三个文件

    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)
  • 相关阅读:
    自我介绍+软工5问
    第一天
    asp.net中使用CKEditor
    没有为扩展名“.html”注册的生成提供程序。.net urlwrite 重写 伪静态 IIs 配置
    局域网内,无法访问SQL2000的解决方法
    企业网站如何做SEO优化
    GridView结合Dropdownlist和Checkbox
    GridView实现删除时弹出确认对话框
    WebResource
    Tech tips(回发、显示名称、DataView过滤前10条记录)
  • 原文地址:https://www.cnblogs.com/mmyy-blog/p/11413955.html
Copyright © 2011-2022 走看看