MySQL с MyISAM и патчи от Meltdown
Есть такие, кто еще сидит на MyISAM? Теперь хотите, не хотите, а сползать с него придется.
Есть такие, кто еще сидит на MyISAM? Теперь хотите, не хотите, а сползать с него придется.

Появилось сообщение, о том что наблюдается потеря производительности в 90% после обновления Linux ядра на сервере, которое теперь содержит KPTI (kernel page-table isolation - защита от Meltdown)

Такие большие потери связаны с запуском MariaDB на старой версии VMware, которая не пробрасывает PCID и INVPCID чипа гостю. Но в безвиртуальной системе удалось добиться регресса в 40%.

Тестовые условия:
----------------------------------
CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 INT) ENGINE=MyISAM;
INSERT INTO t1 (c2) VALUES (FLOOR(1000*RAND()));
INSERT INTO t1 (c2) SELECT FLOOR(1000*RAND()) FROM t1;
-- повторять последнее действия пока не станет хотя бы 1024 строки в t1

SELECT COUNT(*) FROM t1 AS a JOIN t1 AS b WHERE b.c1>a.c1 AND b.c2<a.c1;
----------------------------------

Теперь смотрим время SELECT с KPTI и без:
----------------------------------
rows non-KPTI KPTI regression
1024 0.40 s         0.64 s     37.5%
2048 1.24 s         1.94 s     36.1%
4096 4.22 s         7.05 s     40.1%
8192 16.10 s         26.92 s       40.2%
----------------------------------

Для 8K строк запрос делает более чем 50млн вызовов Handler_read_rnd_next. Для MyISAM этот вызов возвращается вызовом fget(), который в свою очередь возвращается системным вызовом __fget.

Так происходит из-за того, что у движка MyISAM нет кеша строк. В Key Buffer кешируется индекс страниц, а кеша данных строк нету.
Поэтому движок полагается на кеш операционной системы. Это хорошо работает, но, т.к. кеш находится в ядре, то получается, что между MariaDB и и кешем есть системный вызов (syscall).

Изоляция табличных страниц, представленная в KPTI, увеличила нагрузку при системном вызове (syscall). Поэтому вышеуказанная схема, где большое количество MyISAM строк перебираются циклом, работает очень медленно. И замедление только увеличивается, если строка уже находится в кеше.

Как это побороть? - Никак, т.к. это потребует полного редизайна MyISAM.

Хорошая новость заключается в том, что большинство других движков имеют свой кеш строк. У InnoDB это InnoDB Buffer Pool, а у ARIA - ARIA Page Cache.

Вот пример выполнения нашего теста для ARIA со стандартным кешем в 128мегабайт:
----------------------------------
rows non-KPTI KPTI
1024 0.18 s          0.18 s
2048 0.57 s          0.57 s
4096 1.85 s          1.84 s
8192 6.34 s          6.30 s
----------------------------------

Мораль сей басни такова: переезжайте на другой движок и убедитесь, что кеш строк достаточно велик.
Источник: mariadb.org
Источник: mariadb.org
Вы должны войти

loading