【问题标题】:What would happen if I delete the ibdata1 file in my mysql table and replace it with a new empty ibdata1 file?如果我删除 mysql 表中的 ibdata1 文件并用新的空 ibdata1 文件替换它会发生什么?
【发布时间】:2016-09-22 20:39:43
【问题描述】:

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

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

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

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

【问题讨论】:

  • 是的,我检查了那个问题,但我的问题不同.. 请查看编辑
  • 这取决于您所说的“它会起作用” - 它肯定不会像最初那样起作用。您将丢失所有数据。根据您的配置,您也会丢失表结构,但这取决于您如何设置 innodb。您需要更具体地了解您期望的结果。此外,您关于“它无法缩小”的断言也不是真的 - 请参阅此问题以了解原因和可能的解决方案:stackoverflow.com/questions/3456159/…
  • 如果 mysqld 启动时缺少 ibdata1,它会创建文件。您将没有桌子。

标签: mysql innodb


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    如果启用了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;
    

    试试看!!!

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

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

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

    对于导入表格列表,您可以使用一些自动化单行器,例如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 表来列出您想要使用“动态sql”的表。例如,将上面的 $schema 更改为所需的数据库名称。

    【讨论】:

    • 考虑在您的答案中直接发布“this”和“this”。
    猜你喜欢
    • 2013-11-14
    • 1970-01-01
    • 2013-01-18
    • 2019-07-24
    • 1970-01-01
    • 2019-07-17
    • 1970-01-01
    • 2021-04-08
    • 2018-05-11
    相关资源
    最近更新 更多