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

What would happen if I delete the ibdata1 file in my mysql table and replace it with a new empty ibdata1 file?

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

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

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

我打算删除旧的 ibdata1 文件并替换为一个空的 ibdata1 文件,想知道它是否有效。

ibdata1 包含对 InnoDB 至关重要的 InnoDB 字典。如果删除它,对 table 的任何访问都将失败并出现 Table doesn't exist 错误。

如果启用 innodb_file_per_table,则可以通过 this and this.

恢复 table

https://dba.stackexchange.com/a/57157/189538

的公然复制

MyISAM

对于 MyISAM table 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

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

InnoDB

看看这个 InnoDB 的图示

InnoDB Architecture

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

如果您决定接受,您的任务是创建每个 table 并交换 .ibd

在你做任何事情之前,将“\bin\mysql\mysql5.6.12\data”的完整副本复制到另一个

这是一个示例

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

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

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

所需的 SQL

您现在应该执行以下操作

  • mytable.ibd移动到\bin\mysql\mysql5.6.12\data
  • 运行 SQL 创建InnoDB table
  • 登录 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 注册到数据字典中)

在此之后,table mydb.mytable 应该可以完全访问了。您可以通过简单地 运行ning:

来测试可访问性
SELECT * FROM mydb.mytable LIMIT 10;

试一试!!!

负责任地饮酒(数据恢复包含必要的知识)

公然抄袭https://dba.stackexchange.com/a/93511/189538

不作为 MySQL 的一部分,但像 Percona Xtrabackup 这样的工具可以使 exporting/backing 向上 table 的过程更快一些,允许使用正则表达式或列表之类的东西筛选:

要导入 table 的列表,您可以使用一些自动化单行程序,例如 this one found on Bill Karwin tools:

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 table 列出您想要使用 "dynamic sql" 的 table。例如,将上面的 $schema 更改为所需的数据库名称。