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

 更新时间:2013年11月15日 16:05:53   作者:  
从MySQL的Innodb特性中我们知道,Inndob的表空间有共享和独享的特点,如果是共享的。则默认会把表空间存放在一个文件中(ibdata1),当开启独享表空间参数Innodb_file_per_table时,会为每个Innodb表创建一个.ibd的文件。文章讨论在独享表空间卸载、装载、迁移Innodb表的情况

条件:
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

相关文章

  • centos7环境下源码安装mysql5.7.16的方法详解

    centos7环境下源码安装mysql5.7.16的方法详解

    这篇文章主要介绍了centos7环境下源码安装mysql5.7.16的方法,详细分析了centos7环境下MySQL安装的相关步骤、操作命令、配置方法与注意事项,需要的朋友可以参考下
    2020-02-02
  • VPS下修改MySQL root用户密码的方法

    VPS下修改MySQL root用户密码的方法

    VPS下修改MySQL root用户密码的方法,需要的朋友可以参考下。
    2010-12-12
  • MySQL如何使用union all获得并集排序

    MySQL如何使用union all获得并集排序

    这篇文章主要介绍了MySQL如何使用union all获得并集排序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Mysql中正则表达式Regexp常见用法

    Mysql中正则表达式Regexp常见用法

    这篇文章主要介绍了Mysql中正则表达式Regexp常见用法,MySql REGEXP运算符匹配字符串,mysql正则REGEXP学习练习笔记,需要的朋友可以参考下
    2020-02-02
  • mysql数据库修改添加Date格式列的方法

    mysql数据库修改添加Date格式列的方法

    这篇文章主要介绍了关于mysql数据库如何修改添加Date格式的列 ,需要的朋友可以参考下
    2014-07-07
  • mysql事务隔离级别详解

    mysql事务隔离级别详解

    MySQL事务隔离级别是指在多个事务同时执行时,数据库系统如何处理这些事务之间的相互影响。MySQL提供了四种隔离级别:读未提交、读已提交、可重复读和串行化。每种隔离级别都有其优缺点,需要根据具体情况选择合适的级别。
    2023-06-06
  • Mysql启动报ERROR:2002的分析与解决

    Mysql启动报ERROR:2002的分析与解决

    这篇文章主要给大家介绍了关于Mysql启动时报ERROR:2002问题的分析与解决方法,文中通过示例代码介绍将该问题分析的非常详细,对同样遇到这个问题的朋友们具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-08-08
  • MySQL安全删除binlog日志的详细步骤

    MySQL安全删除binlog日志的详细步骤

    如果你的 Mysql 搭建了主从同步,或者数据库开启了log-bin日志,那么随着时间的推移,你的数据库data目录下会产生大量的日志文件,下面这篇文章主要给大家介绍了关于MySQL安全删除binlog日志的详细步骤,需要的朋友可以参考下
    2024-02-02
  • windows10下mysql 8.0 下载与安装配置图文教程

    windows10下mysql 8.0 下载与安装配置图文教程

    这篇文章主要介绍了windows10下mysql 8.0 下载与安装配置图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • mysql如何按字段查询重复的数据

    mysql如何按字段查询重复的数据

    这篇文章主要介绍了mysql如何按字段查询重复的数据问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05

最新评论