mysql 导入tablespace_【MySQL】Transportable TableSpace(TTS) 使用详解

将大的InnoDB表从一个实例,迁移到另一个实例,有很多的方法,在5.6之前常用的是通过物理或者逻辑备份来实现。

在5.6.6+的版本中(5.6、5.7应该是现在的标配吧),用到了一种基于表空间迁移的快速方法,即类似Oracle TTS。

使用

用起来十分简单,此处将实例1上的表数据通过TTS方式导入实例2

① 在实例1上创建测试数据:1mysql1> CREATE TABLE tts(id int PRIMARY KEY AUTO_INCREMENT, name char(128));

2Query OK, 0 rows affected (0.01 sec)

3mysql1> INSERT INTO tts(name) VALUES(REPEAT(‘a’,128));

4Query OK, 1 row affected (0.00 sec)

5mysql1> INSERT INTO tts(name) SELECT name FROM tts;

6Query OK, 1 row affected (0.00 sec)

7Records: 1 Duplicates: 0 Warnings: 0

8mysql1> INSERT INTO tts(name) SELECT name FROM tts;

9Query OK, 2 rows affected (0.00 sec)

10Records: 2 Duplicates: 0 Warnings: 0

11………………………………

12mysql1> INSERT INTO tts(name) SELECT name FROM tts;

13Query OK, 262144 rows affected (2.15 sec)

14Records: 262144 Duplicates: 0 Warnings: 0

可看到已产生92M的ibd文件1mysql1> \! du -sh /data/mysql/test/tts*

212K /data/mysql/test/tts.frm

392M /data/mysql/test/tts.ibd

② 在实例2上创建和实例1相同表结构的表,并执行:1SET sql_log_bin=0;

2ALTER TABLE tts DISCARD TABLESPACE;

3SET sql_log_bin=1; -- 或关掉会话

此处三个感叹号。该操作会记录binlog,可临时不记binlog。1| mysql57-bin.000012 | 259 | Query |  57 |   365 | use `test`; ALTER TABLE a DISCARD TABLESPACE |

③ 对实例1的该表执行FLUSH TABLE $tb_name FOR EXPORT:1mysql1> FLUSH TABLE tts FOR EXPORT;

2Query OK, 0 rows affected (0.05 sec)

3-- 此处产生多了一个cfg文件

4mysql1> \! du -sh /data/mysql/test/tts*

54.0K /data/mysql/test/tts.cfg

612K /data/mysql/test/tts.frm

792M /data/mysql/test/tts.ibd

④ 将实例1的/data/mysql/test/tts.{ibd,cfg}文件拷到实例2所在的datadir对应的库目录中,并为俩文件赋权。

⑤ 恢复实例1中test.tts表的可用性(此时cfg文件已回收):1mysql1> UNLOCK TABLES;

2Query OK, 0 rows affected (0.00 sec)

3mysql1> \! du -sh /data/mysql/test/tts*

412K /data/mysql/test/tts.frm

592M /data/mysql/test/tts.ibd

⑥ 将表空间ibd文件恢复至实例2的test.tts表:1mysql2> ALTER TABLE tts IMPORT TABLESPACE;

2Query OK, 0 rows affected (0.93 sec)

3mysql2> SELECT count(*) FROM tts;

4+----------+

5| count(*) |

6+----------+

7| 524288   |

8+----------+

91 row in set (0.34 sec)

至此,已经将mysql1实例上的tts表中数据快速地迁移到mysql2实例上了。

过程解析

① discard tablespace

为表加MDL锁,删除change buffer所有相关的缓存项,设置表元数据信息,标志tablespace为删除状态,重新生成表的id,保证基于表id的操作后续均会失败,再将idb文件干掉,在②中的两次du可以看到.idb文件已经被删除了。这是一个十分危险的操作,慎重;此操作也会记录binlog,若在复制结构可能会有意想不到的灾难,切记先临时关闭binlog。

② flush table … for export

为表加共享锁,将purge coordinator thread

(在并行复制中的sql thread被称为coordinator)停止,并且将脏页强制同步到磁盘,创建并将test.tts表的元数据写入.cfg文件;

FLUSH TABLES … FOR EXPORT在error log中体现了这个过程:1[Note] InnoDB: Sync to disk of ‘”test”.”tts”‘ started.

2[Note] InnoDB: Stopping purge

3[Note] InnoDB: Writing table metadata to ‘./test/tts.cfg’

4[Note] InnoDB: Table ‘”test”.”tts”‘ flushed to disk

③ unlock tables

此时.cfg文件被删掉,purge coordinator thread

也会重新启动;

(在做flush table … for export时不能断开会话,避免锁释放造成.cfg文件删除)

UNLOCK TABLES

在error log中记录为:1[Note] InnoDB: Deleting the meta-data file ‘./test/tts.cfg’

2[Note] InnoDB: Resuming purge

④ import tablespace

将从实例1上传输过来的.ibd文件和导入到tts表中,此时.cfg文件也必须存在;

ALTER TABLE … IMPORT TABLESPACE在

error log中记录为:1[Note] InnoDB: Importing tablespace for table ‘test/tts’ that was exported from host ‘$host1’

2[Note] InnoDB: Phase I – Update all pages

3[Note] InnoDB: Sync to disk

4[Note] InnoDB: Sync to disk – done!

5[Note] InnoDB: Phase III – Flush changes to disk

6[Note] InnoDB: Phase IV – Flush complete

7[Note] InnoDB: “test”.”tts” autoinc value set to 786406

过程为读取cfg文件:表定义,索引定义,索引RootPage,列定义等等。

再读取import文件每一个page,检查完整性,根据读取到的cfg文件,重新设置当前表的元数据信息。

MySQL TTS的限制:

〇 两个实例都必须开启独立表空间(innodb_file_per_table=1)

〇 迁移的两个实例的innodb_page_size必须一致,并且mysql server版本建议一致

〇 不支持在分区表上执行discard tablespace

〇 不支持在有主外键关系的表上执行discard tablespace,除非设置foregin_key_checks=0


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部