MySQL 清理孤立表 innoDB

标签 mysql innodb orphan

我有一个 MySQL 服务器,其中有很多孤立表。根据手册我需要:

In the database directory, rename the #sql-*.frm file to match the base name of the orphan intermediate table

我拥有的文件(其中一些)如下:

#sql-15655_a541c.frm
#sql-15655_a541e.frm
#sql-15655_a543a.frm
#sql-15655_a543c.frm
#sql-15655_a543d.frm
#sql-15655_a543e.frm
#sql-15655_a5440.frm
#sql-15655_a5442.frm
#sql-15655_a5443.frm
......

ibd 文件是(嗯......其中一些!):

#sql-ib2015-2421921804.ibd
#sql-ib2016-2421921806.ibd
#sql-ib2017-2421921808.ibd
#sql-ib2020-2421921814.ibd
#sql-ib2021-2421921816.ibd

所以,我的目的是从终端执行以下操作:

mv \#sql-15655_a541c.frm \#sql-ib2015-2421921804.frm

我刚刚拿起第一个 frm 并将其移动到第一个 ibd 文件,保留 ibd 名称和 frm 扩展名。因此,我将对第二个、第三个等文件执行相同的操作。然后我将删除带有 #mysql50# 前缀的表。

顺序重要吗?如果我用第五个 ibd 文件的文件名重命名第一个“frm”文件会怎么样?这会导致数据库损坏/损坏吗?你怎么知道如何将frm与ibd文件关联起来?我需要停止mysql服务器吗?

谢谢您的宝贵时间!

最佳答案

https://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting-datadict.html说:

The .frm file must have the same table schema as the orphan intermediate table (it must have the same columns and indexes) and must be placed in the database directory of the orphan intermediate table.

如果 .frm 文件必须具有相同的列和索引,那么是的,您必须将正确的 .frm 文件与正确的 .ibd 文件相匹配。我不知道这些临时文件名是如何生成的。似乎没有任何明显的相关性,因此几乎不可能知道哪一个与另一个相匹配。

您可以使用 MySQL 实用程序中的 mysqlfrm 工具从 .frm 文件转储原始表结构。有一个很好的博客展示了如何执行此操作:https://www.percona.com/blog/2014/01/02/recover-table-structure-frm-files-mysql-utilities/

你应该download the MySQL Utilities很快,因为 Oracle 似乎已经弃用了这些工具。这些工具的一些功能已作为 MySQL Shell 的一部分重新实现,但我预计 .frm 文件的任何功能都将不受支持,因为 MySQL 8.0 不再使用 .frm 文件。

我刚刚尝试在 Macbook 上使用 mysqlfrm,但收到此错误:

ERROR: Cannot find location of mysql_system_tables.sql.

我猜这是因为 MySQL 安装在我的 Macbook 上的/usr/local 下。也许在 Linux 服务器上会更成功,但我手边没有安装了 MySQL 实用程序的 Linux 安装。

这只是故事的一半。您仍然需要了解每个 .ibd 文件的表结构,以将其与正确的 .frm 文件匹配。您也许可以将这些 INFORMATION_SCHEMA 表中的信息拼凑在一起:

  • INNODB_SYS_TABLES
  • INNODB_SYS_COLUMNS
  • INNODB_SYS_INDEXES

例如,这是我的测试架构中的一个简单表:

CREATE TABLE `A` (
  `c1` int(11) NOT NULL DEFAULT '0',
  `c2` int(11) DEFAULT NULL,
  `c3` int(11) DEFAULT NULL,
  PRIMARY KEY (`c1`),
  KEY `c2` (`c2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

如果我查询 I_S 表:

mysql> select * from innodb_sys_tables where name = 'test/A';
+----------+--------+------+--------+-------+-------------+------------+---------------+
| TABLE_ID | NAME   | FLAG | N_COLS | SPACE | FILE_FORMAT | ROW_FORMAT | ZIP_PAGE_SIZE |
+----------+--------+------+--------+-------+-------------+------------+---------------+
|     2126 | test/a |    1 |      6 |  2106 | Antelope    | Compact    |             0 |
+----------+--------+------+--------+-------+-------------+------------+---------------+

mysql> select * from innodb_sys_columns where table_id = 2126;
+----------+------+-----+-------+--------+-----+
| TABLE_ID | NAME | POS | MTYPE | PRTYPE | LEN |
+----------+------+-----+-------+--------+-----+
|     2126 | c1   |   0 |     6 |   1283 |   4 |
|     2126 | c2   |   1 |     6 |   1027 |   4 |
|     2126 | c3   |   2 |     6 |   1027 |   4 |
+----------+------+-----+-------+--------+-----+

mysql> select * from innodb_sys_indexes where table_id = 2126;
+----------+---------+----------+------+----------+---------+-------+
| INDEX_ID | NAME    | TABLE_ID | TYPE | N_FIELDS | PAGE_NO | SPACE |
+----------+---------+----------+------+----------+---------+-------+
|     3875 | PRIMARY |     2126 |    3 |        1 |       3 |  2106 |
|     3876 | c2      |     2126 |    0 |        1 |       4 |  2106 |
+----------+---------+----------+------+----------+---------+-------+

关于MySQL 清理孤立表 innoDB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54943867/

相关文章:

mysql - Count() 返回 0 而不是 NULL

mysql - 选择重复项会为每个查询提供不同的结果计数

rust - 为什么使用我的类型作为外部类型合法的参数来实现外部特征?

java - 级联 ="all-delete-orphan"在与连接表的 Hibernate 单向多对多关联中有任何意义吗?

php - 可捕获的错误 - 参数必须是 PDO 的实例

php - 即使查询有效,mysqli_fetch_array 错误;以 NULL 值运行总导出

mysql - 让 JNDI 与 RDS 一起工作

mysql - innodb 表最后修改日期

mysql - 说明 - 默认外键约束 - InnoDB

java - Hibernate - 一对多关系和 orphanRemoval 级联