У нас есть комбинированное приложение / MySQL-сервер, который начал рушиться. Прямо сейчас он застревает при копировании таблицы MySQL MyISAM со 125 миллионами строк (INSERT INTO a_copy SELECT * FROM a
с участием KEYS DISABLED
на a_copy
). Мы протестировали работу, частью которой является этот запрос, на производственные данные в клонированной производственной виртуальной машине менее чем за час. Однако при выполнении этого задания в производственной среде запрос копирования выполнялся более 12 часов без завершения, что случайным образом делало каждый запрос MySQL медленнее, чем патока (60+ секунд, без каких-либо блокировок).
Вывод из 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
Как мне это интерпретировать?
РЕДАКТИРОВАТЬ: Хотя ошибка определена правильно, это решение не помогает. Когда MySQL ADD PRIMARY KEY
s, он снова копирует таблицу, похожую на INSERT INTO a_copy SELECT * FROM a
, что снова приводит к той же проблеме. Посмотрите мой другой ответ в этой теме.
Итак, я понял это, просмотрев размеры файлов в /var/lib/mysql/<mydb>/a*
, где индексный файл (.MYI
) имел значительный и постоянно растущий размер файла.
DISABLE KEYS
отключает только неуникальные ключи в целом и оставляет активными в частности первичные ключи. В основном 125М-рядный INSERT INTO
заключил 125M индексные вставки на объединенном PRIMARY KEY, который проявляется как случайная запись на диск, что, в свою очередь, является самым дорогостоящим из того, что вы можете сделать с диском.
Итак, мое решение - DROP PRIMARY KEY
на a_copy
таблица во время копирования, а затем ADD PRIMARY KEY
как только это будет сделано.
Лучшее решение, которое я нашел и принятое в производстве, было найдено в 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
, где первичный ключ a равен (aID, aOtherColumn
).
Хотя я не совсем доволен им, он работает достаточно хорошо и, прежде всего, намного лучше, чем оригинальная версия.