MySqlDump的DISABLE KEYS对导入无效


10

我对我之前关于Inno-Tables的导入速度的问题有一个后续问题(惊奇!)。

方案
我尝试在合理的时间内在本地开发计算机上导入一些big *数据库转储。我们KEY在表上附加了许多s,这些表原来是瓶颈,但对于我们的实时系统仍然很重要。

在问完上述问题后,我的方法是KEY ...从转储,导入和重新添加键中删除语句。

但是,我经常发现自己正在编辑当前的转储以将其导入本地,并且偶然发现了这些有趣的“注释”(- disable/enable keys行)

--
-- Dumping data for table `monster`
--

LOCK TABLES `monster` WRITE;
/*!40000 ALTER TABLE `monster` DISABLE KEYS */;
INSERT  INSERT  INSERT
/*!40000 ALTER TABLE `monster` ENABLE KEYS */;
UNLOCK TABLES;

但实际上,这些“注释”是有条件的MySql语句

这对我来说是个新闻,但好的,鉴于输出形式mysql --version对我来说一切正常: mysql Ver 14.14 Distrib 5.5.38, for debian-linux-gnu (x86_64) using readline 6.3

我假设
表已锁定(很好,开发mashine上只有我一个人)。然后,禁用表模式中定义的键,导入数据,启用键。
因此,在“数据插入”阶段,不应浪费时间在键上,而应在插入所有数据之后进行检查。

我会以为这是相同的行为,就好像我KEY 'foo' (foo)'从转储中删除所有-lines,导入转储并ADD KEY 'foo' ...随后运行脚本一样。

我观察到的
是手动删除密钥,导入和重新添加密钥,然后依靠DISABLE KEYS创建我的条件语句更快的方法mysqldump

手动编辑转储+ mysql导入+添加键= 15 + 8 + 8≈30min
普通mysql导入:放弃了,(我每天只得到8个小时的报酬> :))

我忍不住想,我在这里错过了一些非常基本的东西(或者数据库在拖我)。


2
短期:mysqldump --innodb-optimize-keys从Percona 使用percona.com/doc/percona-server/5.5/management/…长期:停止使用mysqldump并使用mydumper或xtrabackup。
jynus 2014年

Answers:


12

你不能依靠DISABLE KEYS;ENABLE KEYS;InnoDB的,因为它没有在InnoDB存储引擎来实现。运行ALTER TABLE ... DISABLE KEYS;并且ALTER TABLE ... ENABLE KEYS;是为MyISAM设计的。正如它在MySQL文档中ALTER TABLE所说的:

如果在MyISAM表上使用ALTER TABLE,则将在单独的批处理中创建所有非唯一索引(对于REPAIR TABLE)。当您有很多索引时,这应该会使ALTER TABLE更快。

对于MyISAM表,可以显式控制密钥更新。使用ALTER TABLE ... DISABLE KEYS告诉MySQL停止更新非唯一索引。然后使用ALTER TABLE ... ENABLE KEYS重新创建丢失的索引。MyISAM使用一种特殊的算法来执行此操作,该算法比逐个插入密钥快得多,因此在执行批量插入操作之前禁用密钥应该可以大大提高速度。除了前面提到的特权外,使用ALTER TABLE ... DISABLE KEYS还需要INDEX特权。

虽然禁用了非唯一索引,但是对于诸如SELECT和EXPLAIN之类的语句,它们将被忽略,否则将使用它们。

在这种情况下,从未提及InnoDB。 ALTER TABLE ... DISABLE/ENABLE KEYS;

即使您ALTER TABLE ... DISABLE KEYS;针对InnoDB表运行,它也会生成警告:

mysql> show create table mytimes\G
*************************** 1. row ***************************
       Table: mytimes
Create Table: CREATE TABLE `mytimes` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `totalTime` int(11) NOT NULL,
  `totalTimeDesc` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> alter table mytimes disable keys;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> show warnings;
+-------+------+-------------------------------------------------------------+
| Level | Code | Message                                                     |
+-------+------+-------------------------------------------------------------+
| Note  | 1031 | Table storage engine for 'mytimes' doesn't have this option |
+-------+------+-------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

这就是为什么没有影响。请回想一下,@ jynus在项目符号7中的回答中提到了同一件事

还请记住,MyISAM将数据和索引保存在两个单独的文件中(.MYD表示数据,.MYI表示索引),因此禁用和启用索引很简单。InnoDB将主键和行数据保留在相同的InnoDB页面中(通过聚集索引)。二级索引将携带PRIMARY KEY作为每个二级索引叶条目的附件。由于数据和索引都通过聚集索引交织在一起,没有人,作为然而,企图实施DISABLE KEYSENABLE KEYSInnoDB中。


1
“我告诉过你” :-)
jynus 2014年

@jynus哈哈:-)。您应该将InnoDB的mysqldump注释(dba.stackexchange.com/questions/76565/…)发布为答案。
RolandoMySQLDBA 2014年

@yoshi我正在根据您的原始问题撰写文章,请继续关注。
jynus 2014年

@yosi作为承诺:dbahire.com/...
jynus

@RolandoMySQLDBA,如果InnoDB无法启用/禁用键,它应该给出错误而不是仅仅警告吗?
Pacerier
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.