如何迁移? 从mysql文档中我们了解到,innodb的表空间可以是共享的或独立的。如果是共享表空间,则所有的表空间都放在一个文件里:ibdata1,ibdata2..ibdatan,这种情况下,目前应该还没办法实现表空间的迁移,除非完全迁移,因此不在本次讨论之列;我们只讨
如何迁移?
从mysql文档中我们了解到,innodb的表空间可以是共享的或独立的。如果是共享表空间,则所有的表空间都放在一个文件里:ibdata1,ibdata2..ibdatan,这种情况下,目前应该还没办法实现表空间的迁移,除非完全迁移,因此不在本次讨论之列;我们只讨论独立表空间的情况。
不管是共享还是独立表空间,innodb每个数据表的元数据(metadata)总是保存在 ibdata1 这个共享表空间里,因此该文件必不可少,它还可以用来保存各种数据字典等信息。数据字典中,会保存每个数据表的id号,每次发生数据表空间新增时,都会使得该id自增一个值(++1),例如:create table xx engine = innodb / alter table xx engine = innodb 都会使得id值增加。
有了上面的理解,想要实现innodb表空间文件的平滑迁移就很容易了,呵呵。下面是一些例子:
假定我们有2台db主机,一个是a,一个b,现在想把a上的某个innodb表空间文件迁移到b上直接用。
一、迁移失败的例子
直接从a上把表空间文件 yejr.ibd 拷贝到 b 上后,导入表空间,报错,无法使用。这是由于a,b上创建该表时的顺序不一致,导致表的id不一样,无法导入。
注意:在这里,表空间文件直接拷贝的前提是该表空间处于干净状态下,也就是所有的数据均已经刷新到磁盘中,否则可能导致无法使用或部分数据丢失。
1. 在b上将旧的表空间废弃
(root@imysql.cn/17:52:47)[yejr]>alter table yejr discard tablespace;query ok, 0 rows affected (0.00 sec)
2. 拷贝到目标机器
scp yejr.ibd b:/home/mysql/yejr/yejr.ibd....
3. 启用该表空间
(root@imysql.cn/17:52:47)[yejr]>alter table yejr import tablespace;error 1030 (hy000): got error -1 from storage engine
4. 查看错误
innodb: operating system error number 13 in a file operation.
innodb: the error means mysqld does not have the access rights to
innodb: the directory.
innodb: error: trying to open a table, but could not
innodb: open the tablespace file './test/b.ibd'!
innodb: error: cannot reset lsn's in table `test/b`
innodb: in alter table ... import tablespace
5. 很明显,是权限的问题,修正过来,然后重新导入
(root@imysql.cn/17:52:47)[yejr]>alter table yejr discard tablespace;error 1030 (hy000): got error -1 from storage engine
6. 怎么还是错误?继续看日志
innodb: error: tablespace id in file './yejr/yejr.ibd' is 15, but in the innodbinnodb: data dictionary it is 13.innodb: have you moved innodb .ibd files around without using theinnodb: commands discard tablespace and import tablespace?innodb: please refer toinnodb: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.htmlinnodb: for how to resolve the issue.innodb: cannot find or open in the database directory the .ibd file ofinnodb: table `yejr/yejr`innodb: in alter table ... import tablespace
从上面的日志得知,由于在a服务器上,yejr表的id是15,而在b服务器上,yejr表的id却是13,二者不一致,因此迁移失败。
既然只是因为id不一样,而且有了上面的理论基础,我们完全可以人为的让它们的id一致嘛,请看下面的第2次尝试。
二、人工干预下的成功迁移
1. 上面的例子中,b上面的yejr表id为13,而a上面为15;因此只需要让b上的yejr表id增加2就可以了。
(root@imysql.cn/17:52:47)[yejr]>alter table yejr rename to yejr1;query ok, 0 rows affected (0.00 sec)#这个时候,yejr的id变为14(root@imysql.cn/17:52:47)[yejr]>alter table yejr1 rename to yejr;query ok, 0 rows affected (0.00 sec)#这个时候,yejr的id变为15
2. 然后,我们再导入
(root@imysql.cn/17:52:47)[yejr]>alter table yejr import tablespace;query ok, 0 rows affected (0.00 sec)(root@imysql.cn/17:52:47)[yejr]>select count(*) from yejr;+----------+| count(*) |+----------+| 3 |+----------+1 row in set (0.00 sec)
看到了吧,成功了,呵呵。想要让其它id增加的方式也可以重复创建表,根据实际情况或者个人喜好而定了。
以上测试均在mysql 5.0.67版本下通过,只不过显示数据稍作处理了。