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

条件:

2台服务器:A和B,需要A服务器上的表迁移到B服务器。

Innodb表:sysUser,记录数:351781。

以下测试在MySQL 5.5.34中进行。

开始处理:

:在B服务器上建立sysUser表,并且执行:

zjy@B : db_test 09:50:30>alter table sysUser discard tablespace;

:把A服务器表的表空间(ibd)复制到B服务器的相应数据目录。

:修改复制过来的ibd文件权限:

chown mysql:mysql sysUser.ibd

:最后就开始加载:

zjy@B : db_test 10:00:03>alter table sysUser import tablespace;
ERROR 1030 (HY000): Got error -1 from storage engine

报错了,查看错误日志:

131112 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.
131112 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,则会有:

131112 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.
131112 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='',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

更多信息见:

http://www.iamcjd.com/?p=1307 p10~13

http://imysql.cn/2008_12_17_migrate_innodb_tablespace_smoothly

http://www.chriscalender.com/?p=28

Innodb 表空间卸载、迁移、装载的更多相关文章

  1. Innodb 表空间传输迁移数据

    在mysql5.5之前,mysql实例中innodb引擎表的迁移是个头疼的问题,要么使用mysqldump导出,要么使用物理备份的方法,但是在mysql5.6之后的版本中,可以使用一个新特性,方便地迁 ...

  2. MySQL Innodb表空间不足的处理方法

    官方给出的解决方案: 添加和删除 InnoDB 数据和日志文件 这一节描述在InnoDB表空间耗尽空间之时,或者你想要改变日志文件大小之时,你可以做的一些事情. 最简单的,增加InnoDB表空间大小的 ...

  3. 10. InnoDB表空间加密

    10. InnoDB表空间加密 InnoDB支持存储在单独表空间中的表的数据加密 .此功能为物理表空间数据文件提供静态加密. 详细信息见官方文档

  4. ibd2sdi — InnoDB表空间SDI提取实用程序

    参考mysql8.0官方文档 https://dev.mysql.com/doc/refman/8.0/en/ibd2sdi.html ibd2sdi是一个实用程序,用于从表空间文件中提取 序列化的字 ...

  5. MySQL InnoDB表空间加密

    从 MySQL5.7.11开始,MySQL对InnoDB支持存储在单独表空间中的表的数据加密 .此功能为物理表空间数据文件提供静态加密.该加密是在引擎内部数据页级别的加密手段,在数据页写入文件系统时加 ...

  6. Innodb表空间迁移过程

    1.大致流程 将a实例的表的数据迁移到b实例上. 1.在目标实例b上创建一个相同的表 2.在目标库b上执行ALTER TABLE t DISCARD TABLESPACE; 3.在源库a上执行FLUS ...

  7. InnoDB表空间、段、区

    1. 表空间是InnoDB存储引擎逻辑结构的最高层,所有的数据都存放在表空间中.默认,InnoDB存储引擎只有一个表空间ibdata1,即所有数据都存放在这个表空间内.如果用户启用了参数innodb_ ...

  8. Innodb表空间

    Innodb有两种管理表空间的方法 独立表空间:每一张表都会生成独立的文件来进行存储,每一张表都有一个.frm表描述文件,和一个.ibd文件.其中ibd文件包括了单独一个表的数据内容和索引内容. 共享 ...

  9. EXPDP/IMPDP与EXP/IMP在不同用户和表空间之间迁移数据的实现方法

    1. EXPDP/IMPDP方式 SQL> create user zlm identified by zlm; User created. SQL> grant connect,reso ...

随机推荐

  1. Jetty与tomcat的比较

    Google 应用系统引擎最初是以 Apache Tomcat 作为其 webserver/servlet 容器的,但最终将切换到 Jetty 上. 这个决定让许多开发人员都诧异的想问:为什么要做这样 ...

  2. 【转】【整理】将Linux脚本中的正常输出,警告,错误等信息输出到文件中

     本文来自:http://blog.csdn.net/woshinia/article/details/18040063   很早以前  编译的时候 就在用 2>&1,但是一直没有生成一 ...

  3. Java字节流:BufferedInputStream BufferedOutputStream

    -----------------------------------------------------------------------------------BufferedInputStre ...

  4. c# 获取系统时间

    //获取日期+时间DateTime.Now.ToString();             // 2008-9-4 20:02:10DateTime.Now.ToLocalTime().ToStrin ...

  5. 7个Linux和Ubuntu下的免费CSS编辑器

    一个好的编辑器是世界上所有程序员和web开发人员梦寐以求的东西.代码编辑器和集成开发环境是程序员工作时的左膀右臂.还在纠结使用什么编辑器么?下面我们将推荐7个主要用于Linux操作系统的免费CSS代码 ...

  6. Linux下C语言高手成长路线(转载)

    建议学习路径: 首先先学学编辑器,vim, emacs什么的都行. 然后学make file文件,只要知道一点就行,这样就可以准备编程序了. 然后看看<C程序设计语言>K&R,这样 ...

  7. 关于QString::toWCharArray 无法解析的外部符号

    1>CommManger.obj : error LNK2019: 无法解析的外部符号 "public: int __thiscall QString::toWCharArray(un ...

  8. hdu1026.Ignatius and the Princess I(bfs + 优先队列)

    Ignatius and the Princess I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (J ...

  9. Python 集合set添加删除、交集、并集、集合操作符号

    在Python中集合set是基本数据类型的一种,它有可变集合(set)和不可变集合(frozenset)两种.创建集合set.集合set添加.集合删除.交集.并集.差集的操作都是非常实用的方法. 1. ...

  10. 查询oracle数据库中的所有表空间信息

    "空闲比例" totalspace,sum(t.blocks) totalblocks from dba_data_files t group by t.tablespace_na ...