InnoDB--------獨立表空間平滑遷移

1. 背景

   * InnoDB的表空間可以是共享的或獨立的。如果是共享表空間,則所有的表空間都放在一個文件裏:ibdata1,ibdata2..ibdataN,這種情況下,目前應該還沒辦法實現表空間的遷移,除非完全遷移。

  * 不管是共享還是獨立表空間,InnoDB每個數據表的元數據(metadata)總是保存在 ibdata1 這個共享表空間裏,因此該文件必不可少,它還可以用來保存各種數據字典等信息。

   * 獨立表空間中數據文件單獨存放在.ibd文件中。

   * MySQL 5.6版本開始支持獨立表空間導入與導出。


2. 環境 [ 2臺DB實例, MySQL 5.6表遷移至MySQL5.7 ]

wKiom1lwyB7iW4nOAABhIqWgD9E628.jpg

   * 源實例 MySQL

mysql> show variables like 'innodb%version';
+----------------+--------+
| Variable_name  | Value  |
+----------------+--------+
| innodb_version | 5.6.36 |
+----------------+--------+
1 row in set (0.01 sec)

mysql> show variables like 'datadir';
+---------------+--------------------+
| Variable_name | Value              |
+---------------+--------------------+
| datadir       | /data/mysql_data6/ |
+---------------+--------------------+
1 row in set (0.00 sec)


   * 目的實例 MySQL 

mysql> show variables like 'innodb%version';
+----------------+--------+
| Variable_name  | Value  |
+----------------+--------+
| innodb_version | 5.7.18 |
+----------------+--------+
1 row in set (0.00 sec)

mysql> show variables like 'datadir';
+---------------+--------------------+
| Variable_name | Value              |
+---------------+--------------------+
| datadir       | /data/mysql_data7/ |
+---------------+--------------------+
1 row in set (0.01 sec)


   * 源實例 MySQL 遷移的數據庫與表信息

mysql> select database();
+------------+
| database() |
+------------+
| mytest     |
+------------+
1 row in set (0.00 sec)

mysql> show create table users;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                                                      |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| users | CREATE TABLE `users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `sex` enum('M','F') NOT NULL DEFAULT 'M',
  `age` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

mysql> select * from users;
+----+-------+-----+-----+
| id | name  | sex | age |
+----+-------+-----+-----+
|  1 | tom   | M   |  25 |
|  2 | jak   | F   |  38 |
|  3 | sea   | M   |  43 |
|  4 | lisea | M   |  36 |
+----+-------+-----+-----+
4 rows in set (0.00 sec)


3. 平滑遷移實戰 [ 遷移mytest數據庫下users表 ]

   * 目的MySQL實例創建相同的數據庫與表 [ MySQL 5.7中創建表需要指定row_format=compact ]

mysql> create database mytest character set utf8mb4;
Query OK, 1 row affected (0.03 sec)

mysql> use mytest;
Database changed
mysql> CREATE TABLE `users` (
    ->   `id` bigint(20) NOT NULL AUTO_INCREMENT,
    ->   `name` varchar(255) NOT NULL,
    ->   `sex` enum('M','F') NOT NULL DEFAULT 'M',
    ->   `age` int(11) NOT NULL DEFAULT '0',
    ->   PRIMARY KEY (`id`)
    -> ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 row_format=compact;
Query OK, 0 rows affected (0.59 sec)

mysql> system ls -l /data/mysql_data7/mytest/
total 64
-rw-r----- 1 mysql mysql    67 Jul 18 05:21 db.opt
-rw-r----- 1 mysql mysql  8648 Jul 18 05:21 users.frm
-rw-r----- 1 mysql mysql 49152 Jul 18 05:21 users.ibd


   * 目的MySQL實例丟棄表空間

mysql> alter table users discard tablespace;
Query OK, 0 rows affected (0.01 sec)

mysql> system ls -l /data/mysql_data7/mytest/
total 16
-rw-r----- 1 mysql mysql   67 Jul 18 05:21 db.opt
-rw-r----- 1 mysql mysql 8648 Jul 18 05:21 users.frm


   * 源MySQL實例刷新表至磁盤並加lock,並且當前表quiesce狀態,只讀,且創建.cfg metadata文件

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


   * 從源MySQL實例服務止拷貝表文件users.ibd, users.cfg文件至目的MySQL實例中

[root@MySQL ~]# cp -v /data/mysql_data6/mytest/users.{cfg,ibd} /data/mysql_data7/mytest/
`/data/mysql_data6/mytest/users.cfg' -> `/data/mysql_data7/mytest/users.cfg'
`/data/mysql_data6/mytest/users.ibd' -> `/data/mysql_data7/mytest/users.ibd'


   * 修改目的MySQL實例數據文件下拷貝文件的所有者與所有組

[root@MySQL ~]# chown -v mysql.mysql /data/mysql_data7/mytest/users.{cfg,ibd}
changed ownership of `/data/mysql_data7/mytest/users.cfg' to mysql:mysql
changed ownership of `/data/mysql_data7/mytest/users.ibd' to mysql:mysql


   * 源MySQL實例釋放lock

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


  * 目的MySQL實例加載表空間

mysql> alter table users import tablespace;
Query OK, 0 rows affected (0.04 sec)


   * 查看目的MySQL實例表數據 [ MySQL5.6數據成功遷移過來 ]

mysql> select * from users;
+----+-------+-----+-----+
| id | name  | sex | age |
+----+-------+-----+-----+
|  1 | tom   | M   |  25 |
|  2 | jak   | F   |  38 |
|  3 | sea   | M   |  43 |
|  4 | lisea | M   |  36 |
+----+-------+-----+-----+
4 rows in set (0.00 sec)


4. 注意問題

   * MySQL 5.6數據遷移到MySQL5.7時,如果創建目的表時不指定row_format,import表數據時會報錯,原因在於MySQL 5.6中是Antelope,在MySQL 5.7中是Barracuda,主要是在表壓縮和行的動態格式上有所改變。


5. 總結

以需求驅動技術,技術本身沒有優略之分,只有業務之分。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章