我们有一个组合应用程序/MySQL 服务器,它已经开始崩溃。现在,它卡在复制 1.25 亿行 MySQL MyISAM 表(开启INSERT INTO a_copy SELECT * FROM a
)。我们已经在克隆的生产 VM 中对生产数据进行了基准测试,该查询所属的作业在不到一小时内就完成了。但是,在生产中运行此作业时,复制查询已运行了 12 多个小时而未完成,随机使每个 MySQL 查询都比糖浆慢(60 多秒,没有任何锁定)。KEYS DISABLED
a_copy
iostat 的输出
yyyy@xxxx:~$ iostat -mxdc 10
Linux 2.6.32-5-686 (xxxx) 12/24/14 _i686_ (4 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
5.24 0.00 1.34 13.43 0.00 80.00
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
sda 1.84 232.18 68.24 468.50 1.88 2.74 17.62 47.19 87.87 0.69 36.79
avg-cpu: %user %nice %system %iowait %steal %idle
0.77 0.00 2.26 27.92 0.00 69.05
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
sda 6.70 6.10 317.30 208.20 1.37 0.83 8.56 140.26 173.99 1.90 100.00
avg-cpu: %user %nice %system %iowait %steal %idle
0.81 0.00 2.58 31.64 0.00 64.97
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
sda 5.00 11.50 372.80 242.80 1.56 1.00 8.54 146.50 321.34 1.62 100.00
avg-cpu: %user %nice %system %iowait %steal %idle
0.17 0.00 1.65 39.42 0.00 58.76
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
sda 3.00 23.40 226.80 618.00 0.94 2.50 8.34 145.54 171.94 1.18 100.00
avg-cpu: %user %nice %system %iowait %steal %idle
0.22 0.00 1.77 32.23 0.00 65.78
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
sda 5.70 22.50 282.10 491.80 1.18 2.02 8.45 145.72 182.10 1.29 100.00
我该如何解释这一点?
答案1
编辑:虽然错误被正确识别,这个解决方案没有帮助。当 MySQL ADD PRIMARY KEY
s 时,它会再次复制类似于 的表INSERT INTO a_copy SELECT * FROM a
,这又会留下相同的问题。请查看我在此主题中的其他回复。
因此,通过观察文件大小,我弄清楚了,/var/lib/mysql/<mydb>/a*
其中索引文件(.MYI
)的文件大小显著且不断增长。
DISABLE KEYS
仅禁用一般的非唯一键,并特别保持主键处于活动状态。基本上,125M 行大小INSERT INTO
的 125M 索引插入到联合主键上,表现为对磁盘的随机写入,而这又是您使用磁盘所能执行的最昂贵的操作。
所以,我的解决方案是在复制时放在桌子DROP PRIMARY KEY
上a_copy
,然后ADD PRIMARY KEY
一旦完成。
答案2
我在生产中找到并采用的最佳解决方案是http://www.mysqldiary.com/if-you-copy-a-myisam-table-with-primary-key-don%E2%80%99t-forget-to-order-the-rows-first/。
使用SHOW INDEX IN a WHERE Key_name='PRIMARY'
,我识别表的主键,并将 附加ORDER BY
到查询中。最终解决方案看起来像INSERT INTO a_copy SELECT * FROM a ORDER BY aID, aOtherColumn
,其中 的主键是 ( aID, aOtherColumn
)。
虽然我对它并不是非常满意,但它运行得相当好,而且最重要的是,比原版好得多。