如果我删除mysql表中的ibdata1文件并将其替换为新的空ibdata1文件,会发生什么?

时间:2016-05-25 10:02:21

标签: mysql innodb

我有一个包含数百个表和数百万条记录的大型数据库。我最近注意到ibdata1文件的大小为360GB。它在我的服务器中占据了巨大的空间。我搜索了几种减少它的方法,发现它无法缩小。

仅供参考,如果我只删除ibdata1文件并在其中创建一个空的新文件会发生什么......

编辑: 在此question中,用户删除了他的文件,并在重新启动'mysqld'服务后无法找到旧数据。

我打算删除旧的ibdata1文件,并使用空的ibdata1文件替换,并想知道它是否可以正常工作。

2 个答案:

答案 0 :(得分:1)

ibdata1包含InnoDB字典,这对InnoDB非常重要。如果删除它,任何对表的访问都将失败,并显示Table doesn't exist错误。

答案 1 :(得分:1)

如果启用了innodb_file_per_table,则可以通过thisthis恢复表。

https://dba.stackexchange.com/a/57157/189538的潜在副本

MyISAM

对于MyISAM表mydb.mytable,您应该有三个文件

  • \bin\mysql\mysql5.6.12\data\mydb\mytable.frm
  • \bin\mysql\mysql5.6.12\data\mydb\mytable.MYD
  • \bin\mysql\mysql5.6.12\data\mydb\mytable.MYI

由于每个文件都包含所需的数据,元数据和索引信息,因此它们应该已经可以作为表访问。它们共同构成表格。没有外部存储引擎机制可以访问。

InnoDB

看看这个InnoDB的图片表示形式

InnoDB Architecture

将ibdata1附加到.ibd文件的唯一方法是数据字典。

如果您决定接受它,您的任务是创建每个表并在.ibd中进行交换

执行任何操作之前,请将“ \ bin \ mysql \ mysql5.6.12 \ data”的完整副本复制到另一个

这是一个样本

假设您有一个数据库mydb和表mytable。这意味着

  • 您拥有文件夹\bin\mysql\mysql5.6.12\data\mydb
  • 在该文件夹中,您拥有
    • mytable.frm
    • mytable.ibd

您需要.frm。如果您看一下我的帖子https://dba.stackexchange.com/questions/44314/how-can-extract-the-table-schema-from-just-the-frm-file/44316#44316,则可以下载一个MySQL实用程序,该实用程序可以生成创建表所需的SQL。

您现在应该执行以下操作

  • mytable.ibd移至\bin\mysql\mysql5.6.12\data
  • 运行SQL创建InnoDB表
  • 登录mysql并运行ALTER TABLE mydb.mytable DISCARD TABLESPACE;(这将删除\bin\mysql\mysql5.6.12\data\mydb\mytable.ibd
  • \bin\mysql\mysql5.6.12\data\mytable.ibd复制到\bin\mysql\mysql5.6.12\data\mydb
  • 登录mysql并运行ALTER TABLE mydb.mytable IMPORT TABLESPACE;(这会将\bin\mysql\mysql5.6.12\data\mydb\mytable.ibd注册到数据字典中)

此后,应该可以完全访问表mydb.mytable。您只需运行以下命令即可测试该可访问性:

SELECT * FROM mydb.mytable LIMIT 10;

尝试一下!

负责任的DRINK(数据恢复结合了必要的知识)

https://dba.stackexchange.com/a/93511/189538的公开副本

不是MySQL的一部分,但是Percona Xtrabackup之类的工具使导出/备份表的过程更快一些,从而允许使用正则表达式或列表进行过滤:

要导入表列表,可以使用诸如this one found on Bill Karwin tools之类的一些自动化oneliner:

mysqldump --no-data $schema > schema-ddl.sql
mysql -N -B <<'EOF' > discard-ddl.sql
SELECT CONCAT('ALTER TABLE `', table_name, '` DISCARD TABLESPACE;') AS _ddl
FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='$schema' AND ENGINE='InnoDB';
EOF
mysql -N -B <<'EOF' > import-ddl.sql
SELECT CONCAT('ALTER TABLE `', table_name, '` IMPORT TABLESPACE;') AS _ddl
FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='$schema' AND ENGINE='InnoDB';
EOF

基本上,您可以使用information_schema.tables表使用“动态sql”列出所需的表。例如,将$schema更改为所需的数据库名称。