我们的生产数据库中有一个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,并且能够成功运行导入,并且没有挂起,也没有进程列表中的表锁消息。
答案 0 :(得分:4)
就我而言,它在重启mysql服务后起作用
sudo service mysql restart
答案 1 :(得分:1)
作为这个问题引用的SA,我想指出一些事情:
对我来说,这意味着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