MySQL MyISAM проблема масштабирования диска / кэш диска - PullRequest
2 голосов
/ 30 октября 2009

У меня есть следующая таблица соответствия:

CREATE TABLE `widgetuser` (
 `widgetuserid` char(40) NOT NULL,
 `userid` int(10) unsigned NOT NULL,
 `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
 PRIMARY KEY (`widgetuserid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 DELAY_KEY_WRITE=1;

У меня есть таблица widgetuser_tmp с той же структурой, но без ключа, и я заполняю таблицу widgetuser этими данными (4 миллиона строк):

mysql> insert into widgetuser select * from widgetuser_tmp limit 0,4000000;flush tables;
Query OK, 4000000 rows affected (33.14 sec)
Records: 4000000  Duplicates: 0  Warnings: 0
Query OK, 0 rows affected (0.91 sec)

Во время записи идет прямо к RAID-1 со скоростью 15 МБ / с, утилита диска

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00  3839.20    0.00   52.40     0.00    15.20   594.20    12.46  237.75   5.57  29.20
sdb               0.00  3839.00    0.00   52.60     0.00    15.20   591.94    14.50  275.59   7.19  37.80

Я вставляю следующие 1 Mio-строки, все нормально, и wMB / s возвращается к 0 сразу после сброса:

mysql> insert into widgetuser select * from widgetuser_tmp limit 4000000,1000000;flush tables;
Query OK, 1000000 rows affected (10.18 sec)
Records: 1000000  Duplicates: 0  Warnings: 0
Query OK, 0 rows affected (0.87 sec)

mysql> insert into widgetuser select * from widgetuser_tmp limit 5000000,1000000;flush tables;
Query OK, 1000000 rows affected (10.21 sec)
Records: 1000000  Duplicates: 0  Warnings: 0
Query OK, 0 rows affected (1.02 sec)

mysql> insert into widgetuser select * from widgetuser_tmp limit 6000000,1000000;flush tables;
Query OK, 1000000 rows affected (10.67 sec)
Records: 1000000  Duplicates: 0  Warnings: 0
Query OK, 0 rows affected (1.17 sec)

Но когда я делаю партию 7mio, результат все равно выглядит так же, но в iostat -mdx sda sdb 5 внезапно мы получаем 100% утилизации в течение 30 секунд:

mysql> insert into widgetuser select * from widgetuser_tmp limit 7000000,1000000;flush tables;
Query OK, 1000000 rows affected (10.73 sec)
Records: 1000000  Duplicates: 0  Warnings: 0
Query OK, 0 rows affected (1.21 sec)

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00    88.60    0.00  295.60     0.00     1.52    10.53   130.60  435.93   3.38 100.00
sdb               0.00    89.20    0.00  300.80     0.00     1.57    10.68   143.99  483.97   3.32 100.00

После сброса файлы данных не затрагиваются:

-rw-rw---- 1 mysql mysql 1032000000 2009-10-30 12:10 widgetuser.MYD
-rw-rw---- 1 mysql mysql  522777600 2009-10-30 12:11 widgetuser.MYI  

А также таблица состояния швов нормальная:

+----------------+--------+---------+------------+----------+----------------+-------------+-------------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+-------------------+---------+
| Name           | Engine | Version | Row_format | Rows     | Avg_row_length | Data_length | Max_data_length   | Index_length | Data_free | Auto_increment | Create_time         | Update_time         | Check_time | Collation       | Checksum | Create_options    | Comment |
+----------------+--------+---------+------------+----------+----------------+-------------+-------------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+-------------------+---------+
| widgetuser     | MyISAM |      10 | Fixed      |  8000000 |            129 |  1032000000 | 36310271995674623 |    522777600 |         0 |           NULL | 2009-10-30 11:59:41 | 2009-10-30 12:10:59 | NULL       | utf8_general_ci |     NULL | delay_key_write=1 |         |
+----------------+--------+---------+------------+----------+----------------+-------------+-------------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+-------------------+---------+

И когда я продолжаю (так как у нас 100% загрузка диска), становится очень быстро:

mysql> insert into widgetuser select * from widgetuser_tmp limit 9000000,1000000;flush tables;
Query OK, 1000000 rows affected (31.93 sec)
Records: 1000000  Duplicates: 0  Warnings: 0
Query OK, 0 rows affected (2.34 sec)

mysql> insert into widgetuser select * from widgetuser_tmp limit 10000000,1000000;flush tables;
Query OK, 1000000 rows affected (2 min 39.72 sec)
Records: 1000000  Duplicates: 0  Warnings: 0
Query OK, 0 rows affected (7.82 sec)

Первичный ключ проверяется, чтобы увидеть, является ли новая запись уникальной или нет. Как только ключ не помещается в память (key_buffer_size = 512MB = около 8 миллионов записей), ему необходимо извлечь недостающие ключевые части из накопителя (-cache) для проверки. Поэтому мы должны видеть больше операций чтения и медленного времени вставки - мы не видим медленных операций чтения, так как ключ буферизуется в кеше диска. Но мой вопрос: кто вдруг так много пишет и где и почему и как я могу это исправить? Любые идеи приветствуются!

Другие идеи и идеи:

  • поскольку случайные записи со скоростью 1 МБ / с следуют за завершенным оператором, уникальная проверка уже пройдена
  • это программный raid-1 с включенным ahci, диски свободны на 93% и способны работать на скорости около 80 ВтМБ / с
  • машина имеет 8 ГБ оперативной памяти, 5 ГБ кэш-памяти, 600 МБ занято MySQL, 1,7 ГБ свободно
  • MySQL 5.1.31-1ubuntu2-log
  • delay_key_write не меняет это поведение
  • myisam_sort_buffer_size = 2 ГБ (не используется здесь, хотя?)
  • key_buffer_size = 512 МБ
  • bin_log выключен
  • Linux 2.6.28-15-сервер # 52-Ubuntu SMP Ср 9 сентября 11:34:09 UTC 2009 x86_64 GNU / Linux

Ответы [ 2 ]

1 голос
/ 30 октября 2009

Из вашего вопроса не совсем понятно, какое поведение вы ожидаете или получаете. Вот некоторые вещи, которые вы можете не знать

  • FLUSH TABLES уничтожает кэш ключей MyISAM - он не только записывает грязные блоки, но и отбрасывает чистые, поэтому каждый индексный блок должен быть извлечен снова для изменения
  • MyISAM по умолчанию использует размер блока 1 КБ, который, вероятно, меньше блоков вашей файловой системы; это может создать проблемы с производительностью
  • Если вы планируете какой-либо срок службы (который, по-видимому, вам не нужен, потому что вы используете MyISAM), то вам следует использовать аппаратный рейд с кэш-памятью с резервным питанием в контроллере.

Я предполагаю, что либо индекс больше не помещается в буфер ключей, либо ему приходится выполнять намного больше операций записи, что инициирует чтение, потому что они небуферизованы для записи за пределами размера блока.

Попробуйте изменить myisam_block_size на 4k или выше и перестройте таблицу (это опция my.cnf-only, которая вступает в силу только для новых таблиц после перезапуска).

Вы можете проверить размер блока на столе с помощью myisamchk -dv

0 голосов
/ 24 мая 2013

Я использую mariadb5528, если использование key_buffer_size> 90%, кажется, что delay_key_write не работает поэтому увеличьте key_buffer_size до 2G.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...