我最近通过在枚举字段中添加一个新值来更改一个巨大的MyISAM表(8000万条)。 在我这样做之后,我检查了用于复制主服务器的2个从服务器上的表的健康状况。 我注意到,在一台从服务器上MYI文件要小得多。 我已经用myisamchk和REPAIR修复了表,但索引的大小没有改变。
请在下面看到在这3台服务器上运行myisamchk -dvv返回的结果为“Keyfile length”:
Master Server Auto increment key: 1 Last value: 80098340 Data records: 79375556 Deleted blocks: 0 Datafile parts: 79375556 Deleted data: 0 Datafile pointer (bytes): 6 Keyfile pointer (bytes): 6 Datafile length: 9635014668 **Keyfile length: 18945252352** Max datafile length: 281474976710654 Max keyfile length: 288230376151710719 Recordlength: 1110 Slave Server 1 Auto increment key: 1 Last value: 80097611 Data records: 79374828 Deleted blocks: 0 Datafile parts: 79394418 Deleted data: 0 Datafile pointer (bytes): 6 Keyfile pointer (bytes): 6 Datafile length: 9635788652 **Keyfile length: 18024821760** Max datafile length: 281474976710654 Max keyfile length: 288230376151710719 Recordlength: 1110 Slave Server 2 - Here the size of Keyfile is much smaller Auto increment key: 1 Last value: 80098312 Data records: 79375002 Deleted blocks: 0 Datafile parts: 79375002 Deleted data: 0 Datafile pointer (bytes): 6 Keyfile pointer (bytes): 6 Datafile length: 9634942908 **Keyfile length: 11092404224** Max datafile length: 281474976710654 Max keyfile length: 288230376151710719
什么可能导致如此显着的差异?
如果您在MyISAM上运行修复,应该减小MYI的大小。 为什么?
当一个mysqldump创build并加载一个MyISAM表时,想一想使用mytable的机械步骤:
CREATE TABLE mytable ... LOCK TABLE mytable ... ALTER TABLE mytable DISABLE KEYS; (shuts off updates to non-unique indexes) INSERT INTO ... INSERT INTO ... . . . ALTER TABLE mytable ENABLE KEYS; (rebuild all indexes) UNLOCK TABLES;
在ALTER TABLE ... ENABLE KEYS ,您运行SHOW PROCESSLIST;
你会看到该进程的信息说, Repair by sorting
完成后,您应该有一个MYI,其中95%的BTREE节点已经满载。
为什么当你修理它时,这么多的空间会消失? 看看相反的情况。
您正在以auto_increment id的数字顺序加载表。 以某种有序的方式加载数据会在BTREE索引中产生不平衡的密钥分配。 在某些情况下,所有的节点可能高达45%的碎片。
例子:如果你有一个二叉树(最糟糕的BTREE)按顺序加载,你会得到一个二叉树,一直向右倾斜,看起来像一个负斜率的链表。
我曾经在我的DBA StackExchange文章中提到过这个疯狂的现象
Aug 03, 2011 : 我应该什么时候重build索引? Jun 28, 2012 : BTREE在MySQL中的好处 Oct 26, 2012 : innodb片段在有点乱序的插入方面有多糟糕? 在mysql客户端运行REPAIR TABLE ,运行myisamchk -r或者重新加载MyISAM的mysqldump,总是会产生一个较小的MyISAM索引文件。