MySQL在导入数据库转储时出现卡顿

5
我们有一个用于从生产数据库导入数据的脚本,我们用它来重建我们的沙盒数据库。我们使用的语法是:mysql -u uname -ppass dbname < prod_db_export.sql。脚本继续创建第一个表,然后执行以下操作:
LOCK TABLES `ad` WRITE;
/*!40000 ALTER TABLE `ad` DISABLE KEYS */;
/*!40000 ALTER TABLE `ad` ENABLE KEYS */;
UNLOCK TABLES;

ad 中没有数据,因此在 DISABLE KEYS 行后没有导入语句。无论如何,此时导入已经挂起,当我们使用 processlist 查询数据库时,会看到以下输出:

| 5116 | uname     | localhost | dbname     | Field List |   85 | Waiting for table |                        | 
| 5121 | uname     | localhost | dbname     | Query      |   44 | Waiting for table | LOCK TABLES `ad` WRITE | 
| 5126 | uname     | localhost | dbname     | Field List |   23 | Waiting for table |                        | 

有人知道是什么原因导致这种情况发生吗?更好的方法是如何解决呢?

我们的SA不想重启mysql,如果可能的话,因为他担心它会无法重新启动(我们上次遇到类似情况时就出现了这种情况,他不得不从备份中重建整个数据库,包括所有沙盒的数据库)。

随后,我们创建了一个新的数据库dbname2,并成功地运行了导入操作,没有挂起,也没有在进程列表中出现表锁信息。


你尝试过文件系统检查吗? - ty812
听起来更像是服务器故障的问题。但是,如果你的系统管理员觉得他不能重新启动服务器,因为它无法正常启动,那么就有更大的问题了。在我看来,重新启动数据库服务器/服务时唯一需要担心的是对用户的停机时间。也许是时候更换一些硬件了 :-) - Littlejon
4个回答

3

在我的情况下,重启mysql服务后它起作用了。

sudo service mysql restart

1

作为这个问题中提到的SA,我想指出一些事情:

  • 在删除DB之前,已删除了ibdata文件(我们使用每个idb表)
  • 然后删除并重新创建数据库
  • 在导入时,第一个表是广告,似乎已经被锁定。

对我来说,这意味着仍然在InnoDB元数据中存储有锁定信息,该元数据保存在共享的ibdata文件中。 上次我遇到InnoDB元数据与单个表ibdata文件不同步的问题时,我彻底清除了所有内容并重新导入。 在那个场合,当我尝试重新启动MySQL时,它拒绝了,因为它无法找到已被删除但仍在元数据中的表ibd文件。

这里持久的问题是通过命令行而不是删除数据库来删除ibd文件。 PEBKAC。


0
在我的情况下,数据库转储尝试将一百万行插入到一个插入语句中。一个正确的转储应该尝试每次在一个插入语句中转储大约1500行。
INSERT INTO `employees` (`id`, `name`) VALUES 
(1, 'jack'),
(2, 'mary'),  
--don't have too many of these rows -- start a new INSERT statement
--However, don't go the other extreme and only insert 1 row per insert statement

0

如果您在删除InnoDB表空间文件之前没有先删除表,那么您将无法管理这些表。服务器甚至可能拒绝启动。

在这种情况下,您需要使用innodb_force_recovery选项。

确保在使用此选项时,没有其他客户端连接并尝试执行任何操作。

您可能需要将innodb_force_recovery设置为3。如果在关闭服务器时存在未提交/回滚的事务,并且InnoDB没有清理它们,则可能需要使用6。

然后,您可以删除表和数据库。再次关闭服务器并将innodb_force_recovery设置回0。

如果仍然有问题,请发布您的MySQL日志的相关部分。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接