MySQL MyISAM + rails tests = bugs

Пришлось мне на днях потюнить MySQL. Решил попробовать разные конфигурации на предмет максимальной производительности по моим задачам. Нарыл ряд статей по  улучшению производительности. Лучше всего ИМХО написано было сдесь.

Пред история. Сразу скажу что запросы у меня простые и короткие. Пара селектов по индесированым полям + инсерт + апдейт. Ничего сложного. Но! В один прекрасный момент СУБД просто брала и начинала жрать все ресурсы процессора как локально так и на продакшин сервере. Однодневный инвестигейт показал интересную вещь. После инсерта происходит перестрой индексов данной таблицы, что само по себе требует ресурсов процессорного времени и это время прямо пропорционально количеству записей в таблице. Таким образом, если мне нужно много циклов записей/селектов подряд то время каждого цикла начинает расти. И у меня оно дошло до 1го цикла в секунду. Это при том что мне нужно это сделать 300к-500к раз. Посчитав примерно во что мне это обойдется вышло что весь цикл будет длиться с недельку. Это естественно ни в какие рамки не лезет.

Посему начал рыть. Сначала в сторону тюнинга СУБД. В целом добился прироста производительности гдето на 10%. Но проблема как обычно была не в СУБД. Т.е. как-бы в СУБД но не в СУБД. В общем это не самое интересное.

Самое интересно это то, что вовремя тюнинга я настроил все базы на использования движка MyISAM. И тут начались спец-эффекты. Упало ряд тестов. Анализ кода ничего не показал. Анализ фикстур, откаты изменений (я работаю в команде посему начал грешить на последние комиты) все это ни к чему не привело.

Начал думать (гуглом). Как оказалось тесты в рельсах работают (в основном) в режиме транзакций. Т.е. каждый тестовый случаю выполняется как транзакция, которая потом (после выполнения тестового случая) откатывается. Теперь о MyISAM, как извесно этот движек не поддерживает транзакций, поэтому ряд тестов модифицируют данные необратимо. С этим и были связаны глюки. Кроме того, глюки будут также если у вас есть модифицирующие хранимые процедуры.

Вердикт. Для тех кто использует MySQL в тестовых версиях используйте движек InnoDB, иначе могут выпасть очень даже интересные глюки. Или используйте PostgreSQL.

Метки: , , , , ,

Комментариев: 4

  1. runmen пишет:

    а
    class Test::Unit::TestCase
    self.use_transactional_fixtures = false

  2. Спок пишет:

    Скорость при таком падает в разы. Откатить транзакцию намного дешевле чем пересоздавать контекст. А когда у тебя с 1к тестов и 5к ассертов то это существенно.

  3. funny_falcon пишет:

    А может, вместо того, чтобы тюнить MySQL действительно использовать PostgreSQL ?
    Правда, его в какой-то момент тоже придётся тюнить… Но может быть этот момент наступит позже.

  4. Спок пишет:

    Честно скажу, что думаю об этом все сильнее и сильнее. Вот грядут майские празднеги - будет время поиграться с постгресом. Благо тестов производительности немеряно внутри прожекта накопилося.
    Единственное, что настораживает это какая то неопределенность с кластером в постгресе. Если мне пару машин нужно будет скомпоновать и задачи раскидать.
    Нужно все это пробовать.

Оставьте свой отзыв!

Блог работает на WordPress.
Подписка RSS: все записи, комментарии.