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)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM