欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

mysql Innodb表空间卸载、迁移、装载的使用方法

程序员文章站 2024-02-25 17:10:09
条件:2台服务器:a和b,需要a服务器上的表迁移到b服务器。innodb表:sysuser,记录数:351781。以下测试在mysql 5.5.34中进行。开始处理:1:在...

条件:
2台服务器:a和b,需要a服务器上的表迁移到b服务器。
innodb表:sysuser,记录数:351781。
以下测试在mysql 5.5.34中进行。
开始处理:
1:在b服务器上建立sysuser表,并且执行:

复制代码 代码如下:

zjy@b : db_test 09:50:30>alter table sysuser discard tablespace;

2:把a服务器表的表空间(ibd)复制到b服务器的相应数据目录。
3:修改复制过来的ibd文件权限:

复制代码 代码如下:

chown mysql:mysql sysuser.ibd

4:最后就开始加载:

复制代码 代码如下:

zjy@b : db_test 10:00:03>alter table sysuser import tablespace;
error 1030 (hy000): got error -1 from storage engine

报错了,查看错误日志:

复制代码 代码如下:

10:05:44  innodb: error: tablespace id and flags in file './db_test/sysuser.ibd' are 2428 and 0, but in the innodb
innodb: data dictionary they are 2430 and 0.
innodb: have you moved innodb .ibd files around without using the
innodb: commands discard tablespace and import tablespace?
innodb: please refer to
innodb: http://dev.mysql.com/doc/refman/5.5/en/innodb-troubleshooting-datadict.html
innodb: for how to resolve the issue.
10:05:44  innodb: cannot find or open in the database directory the .ibd file of
innodb: table `db_test`.`sysuser`
innodb: in alter table ... import tablespace

当遇到这个的情况:a服务器上的表空间id 为2428,而b服务器上的表空间id为2430。所以导致这个错误发生,解决办法是:让他们的表空间id一致,即:b找出表空间id为2428的表(create table innodb_monitor (a int) engine=innodb;),修改成和sysuser表结构一样的的表,再import。要不就把a服务器的表空间id增加到大于等于b的表空间id。(需要新建删除表来增加id)

要是a的表空间id大于b的表空间id,则会有:

复制代码 代码如下:

11:01:45  innodb: error: tablespace id and flags in file './db_test/sysuser.ibd' are 44132 and 0, but in the innodb
innodb: data dictionary they are 2436 and 0.
innodb: have you moved innodb .ibd files around without using the
innodb: commands discard tablespace and import tablespace?
innodb: please refer to
innodb: http://dev.mysql.com/doc/refman/5.5/en/innodb-troubleshooting-datadict.html
innodb: for how to resolve the issue.
11:01:45  innodb: cannot find or open in the database directory the .ibd file of
innodb: table `db_test`.`sysuser`
innodb: in alter table ... import tablespace

这时的情况:a服务器上的表空间id 为44132,而b服务器上的表空间id为2436。(因为a是测试机子,经常做还原操作,所以表空间id已经很大了,正常情况下。表空间id不可能这么大。

既然表空间id不对导致这个错误报出,那我们手动的让b的表空间id追上a的表空间id。

需要建立的表数量:44132-2436 = 41696个,才能追上。因为他本身就需要再建立一个目标表,所以需要建立的表数量为:41695。不过安全起见,最好也不要超过41695,以防b的表空间id超过了a,则比如设置安全的值:41690,即使b没有到达a表空间id的值,也应该差不多了,可以再手动的去增加。用一个脚本跑(需要建立的表比较多),少的话完全可以自己手动去处理:

复制代码 代码如下:

#!/bin/env python
# -*- encoding: utf-8 -*-

import mysqldb
import datetime

def create_table(conn):
    query = '''
create table tmp_1 (id int) engine =innodb
    '''
    cursor = conn.cursor()
    cursor.execute(query)
    conn.commit()
def drop_table(conn):
    query = '''
drop table tmp_1
    '''
    cursor = conn.cursor()
    cursor.execute(query)
    conn.commit()

if __name__ == '__main__':
    conn = mysqldb.connect(host='b',user='zjy',passwd='123',db='db_test',port=3306,charset='utf8')
    for i in range(41690):
        print i
        create_table(conn)
        drop_table(conn)

也可以开启多线程去处理,加快效率。
当执行完之后,再重新按照上面的1-3步骤进行一次,最后再装载:

复制代码 代码如下:

zjy@b : db_test 01:39:23>alter table sysuser import tablespace;
query ok, 0 rows affected (0.00 sec)

要是再提示a表空间id大于b表的话,就再手动的按照脚本里面的方法来增加id,这时候就只需要增加个位数就可以追上a的表空间id了。
总结:
上面只是一个方法,虽然可以迁移innodb,但是出问题之后可能会引其innodb的页损坏,所以最安全的还是直接用mysqldump、xtrabackup等进行迁移。
5.6 可以不用考虑这些tablespace id,可以直接import 进来。

复制代码 代码如下:

2013-11-12 15:25:09 2378 [note] innodb: sync to disk
2013-11-12 15:25:09 2378 [note] innodb: sync to disk - done!
2013-11-12 15:25:09 2378 [note] innodb: phase i - update all pages
2013-11-12 15:25:09 2378 [note] innodb: sync to disk
2013-11-12 15:25:09 2378 [note] innodb: sync to disk - done!
2013-11-12 15:25:09 2378 [note] innodb: phase iii - flush changes to disk
2013-11-12 15:25:09 2378 [note] innodb: phase iv - flush complete