MySQL无法删除表

zcl*_*eft 3 mysql innodb

我有一个损坏的表,无法删除它来恢复它。如何从数据库中删除该表?

当我尝试在表上查询时,这就是我得到的......

mysql> SELECT * FROM tbl_company LIMIT 10;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    4
Current database: us_businessdb

ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.soc            k' (111)
ERROR:
Can't connect to the server
Run Code Online (Sandbox Code Playgroud)

这是错误日志;

2017-08-10T16:11:28.492290Z 4 [ERROR] InnoDB: Trying to access page number 3 in space 35, space name us_businessdb/tbl_company, which is outside the tablespace bounds. Byte offset 0, len 16384, i/o type read. If you get this error at mysqld startup, please check that your my.cnf matches the ibdata files that you have in the MySQL server.
2017-08-10T16:11:28.492335Z 4 [ERROR] InnoDB: Server exits.
2017-08-10T16:11:28.724161Z 0 [Warning] Changed limits: max_open_files: 1024 (requested 5000)
2017-08-10T16:11:28.724259Z 0 [Warning] Changed limits: table_open_cache: 431 (requested 2000)
Run Code Online (Sandbox Code Playgroud)

因此,将力恢复设置为innobd_force_recovery=6这就是我得到的......

mysql> SHOW TABLES;
+-------------------------+
| Tables_in_us_businessdb |
+-------------------------+
| jnct_tbl_user           |
| tbl_company             |
| tbl_contact             |
| tbl_data                |
| tbl_details             |
| tbl_sic                 |
| tbl_user                |
| tbl_zipcode             |
+-------------------------+
8 rows in set (0.00 sec)

mysql> DROP TABLE tbl_company;
ERROR 1051 (42S02): Unknown table 'us_businessdb.tbl_company'
mysql> DROP VIEW  tbl_company;
ERROR 1347 (HY000): 'us_businessdb.tbl_company' is not VIEW
mysql> CREATE TABLE tbl_company ( id int(10));
ERROR 1050 (42S01): Table 'tbl_company' already exists
Run Code Online (Sandbox Code Playgroud)

为了记录,每次我尝试删除该表时,我都会:

  • SET_FOREIGN_KEY_CHECK=0在我尝试删除该表之前。
  • 每次我尝试删除表时仍然收到相同的错误(因此我知道没有部分删除。
  • 在强制恢复中我仍然可以查询其他表

我只想删除该表并使用我最初转储的原始数据重新加载它。

我该怎么做才能解决这个问题?我唯一知道要做的就是手动删除该文件,但是当 MySQL 加载时我会收到错误,我确信必须有更好的方法来做到这一点。

另外,为了记录,我已经多次重新创建了这个数据库,并且作为主表的同一个表不断损坏(这本身就是另一个问题,我将为另一个问题保留)。由于它是 Linux 上的干净 MySQL 服务器安装,之前我只是重新安装了 MySQL 服务器,以消除 MySQL 启动时因丢失文件而手动删除 db 文件的错误,但这很痛苦,我确信有更好的方法方式。

编辑: 当我更新单个列时,这个源自表的损坏表已满错误。我刚刚更新了大约 1200 万条记录,所以我确信这是某个地方的设置问题,因为我的硬盘有足够的空间。

Rol*_*DBA 5

该表us_businessdb.tbl_company可能有损坏的数据字典条目。早在 2015 年 6 月/7 月,我就类似情况(mysqld 访问表数据崩溃)回答了 3 个问题。我对这张桌子的脱离表示哀悼。

如果您有该表数据的先前 mysqldump,则可以将其加载到另一个数据库中。然后,将所有好的表传输到另一个数据库中。

您当前包含损坏表的数据库称为us_businessdb。创建一个具有相似名称的数据库 ( us_business_db) 并将好的内容移入其中。

CREATE DATABASE us_business_db;
ALTER TABLE us_businessdb.jnct_tbl_user RENAME us_business_db.jnct_tbl_user;
ALTER TABLE us_businessdb.tbl_contact   RENAME us_business_db.tbl_contact;
ALTER TABLE us_businessdb.tbl_data      RENAME us_business_db.tbl_data;
ALTER TABLE us_businessdb.tbl_details   RENAME us_business_db.tbl_details;
ALTER TABLE us_businessdb.tbl_sic       RENAME us_business_db.tbl_sic;
ALTER TABLE us_businessdb.tbl_user      RENAME us_business_db.tbl_user;
ALTER TABLE us_businessdb.tbl_zipcode   RENAME us_business_db.tbl_zipcode;
Run Code Online (Sandbox Code Playgroud)

好吧,现在来说说血腥的东西......

你在问题中提到

编辑:当我更新单个列时,这个源自表的损坏表已满错误。我刚刚更新了大约 1200 万条记录,所以我确信这是某个地方的设置问题,因为我的硬盘有足够的空间。

当您尝试在单个查询中更新太多数据UPDATE并遇到table is full错误时,您的硬盘空间并没有用完。空间不足的是 ibdata1 内的撤消日志。我曾经讨论过这个问题Jun 16, 2014MySQL 索引创建在表已满时失败),我个人使用 2TB ibdata1/ibdata2,有人的查询因该错误而失败,即使 ibdata 文件中有 106GB 的未使用空间。未使用的空间用于撤消日志(其中 128 个)。

我更早地讨论过这种情况:

我不能肯定地说“桌子已满”是否破坏了你的桌子。我只是想澄清这个错误的意思。

好的,现在来说说更血腥的东西(血腥是一个词吗?)...

您会发现这里很有趣。运行以下命令:

USE us_businessdb
SHOW TABLES;
Run Code Online (Sandbox Code Playgroud)

你可能会看到这个:

mysql> SHOW TABLES;
+-------------------------+
| Tables_in_us_businessdb |
+-------------------------+
| tbl_company             |
+-------------------------+
Run Code Online (Sandbox Code Playgroud)

你有没有想过为什么 mysqld 在执行时没有崩溃SHOW TABLES;

所做的SHOW TABLES;只是通过数据文件夹寻找.frm文件。

运行此查询

SELECT table_name Tables_in_us_businessdb.
FROM information_schema.tables
WHERE table_schema='us_businessdb';
Run Code Online (Sandbox Code Playgroud)

做完全相同的事情。在这两种情况下,它都会查找tbl_company.frm.

tbl_company.ibd如果您尝试通过执行以下操作来访问 的元数据

SELECT data_length,index_length,create_time,update_time
FROM information_schema.tables
WHERE table_schema='us_businessdb';
Run Code Online (Sandbox Code Playgroud)

或尝试访问实际数据

SELECT * FROM tbl_company LIMIT 10;
Run Code Online (Sandbox Code Playgroud)

然后,mysqld 崩溃并崩溃。

好吧,血淋淋的事情已经说够了。现在怎么办 ???

如果您有该表的 mysqldump tbl_company,您可以将其加载到我们创建的新数据库中 ( us_business_db)。

如果您有原始CREATE TABLE tbl_company命令,则可以在新数据库中执行它。我会将重新加载数据的详细信息留给您。

如果您没有原始CREATE TABLE tbl_company命令,您需要做的就是从tbl_company.frm文件中获取表结构。如何 ???

运行此查询:SELECT @@global.datadir;

假设在此示例中,datadir 是/var/lib/mysql

转到操作系统并使用以下命令转到数据库文件夹tbl_company.frm

cd /var/lib/mysql/us_businessdb
ls -l
Run Code Online (Sandbox Code Playgroud)

您应该看到tbl_company.frmtbl_company.ibd文件。将其复制.frm到另一个文件夹或另一台计算机。

回到Jun 11, 2013我回答的问题如何从 .frm 文件中提取表架构?。在那篇文章中,我写了一些我在Chuck 的博客中看到的有关 mysqlfrm 实用程序的内容。我尝试了一下并且成功了。您必须使用它在新数据库中重新创建空表。

完成后,您可以删除旧数据库,重新创建旧数据库,将表移回旧数据库。

DROP DATABASE us_businessdb;
CREATE DATABASE us_businessdb;
ALTER TABLE us_business_db.jnct_tbl_user RENAME us_businessdb.jnct_tbl_user;
ALTER TABLE us_business_db.tbl_contact   RENAME us_businessdb.tbl_contact;
ALTER TABLE us_business_db.tbl_data      RENAME us_businessdb.tbl_data;
ALTER TABLE us_business_db.tbl_details   RENAME us_businessdb.tbl_details;
ALTER TABLE us_business_db.tbl_sic       RENAME us_businessdb.tbl_sic;
ALTER TABLE us_business_db.tbl_user      RENAME us_businessdb.tbl_user;
ALTER TABLE us_business_db.tbl_zipcode   RENAME us_businessdb.tbl_zipcode;
ALTER TABLE us_business_db.tbl_comnpany  RENAME us_businessdb.tbl_comnpany;
Run Code Online (Sandbox Code Playgroud)

结语

对于损坏的.ibd文件,我们深表歉意。你必须注意这一点。然而,这些步骤将有助于清理数据字典并恢复us_businessdb到某种正常状态。


归档时间:

查看次数:

22008 次

最近记录:

2 年,6 月 前