导入数据库转储时挂起mysql

时间:2009-10-28 19:58:50

标签: mysql import locking

我们的生产数据库中有一个db dump import脚本,用于重建我们的沙箱dbs。我们使用的语法是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,因为他担心它将无法重启(这发生在我们最后一次遇到类似情况时,我不得不重建整个数据库,包括所有数据库sandboxes的dbs,来自备份)。

我们随后创建了一个新数据库dbname2,并且能够成功运行导入,并且没有挂起,也没有进程列表中的表锁消息。

4 个答案:

答案 0 :(得分:4)

就我而言,它在重启mysql服务后起作用

sudo service mysql restart

答案 1 :(得分:1)

作为这个问题引用的SA,我想指出一些事情:

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

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

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

答案 2 :(得分:0)

如果删除inno表空间文件而不先删除表,则根本无法管理表。服务器甚至可能拒绝出现。

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

绝对确保当您使用此选项时,其他任何客户都无法联系并尝试做任何事情。

你可能需要将innodb_force_recovery设置为3.如果在关闭服务器时有正在进行的事务且inno没有干净地提交/回滚它们,那么你可能需要使用6。

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

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

答案 3 :(得分:0)

在我的例子中,数据库转储尝试在一个insert语句中插入一百万行。正确的转储只会尝试在一个插入语句中一次转储大约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