User Tools

Site Tools


Translations of this page:
ru:mysql_tunning

Mysql Tunning

Если вы используете только трейд - эта статья не имеет особого значения, тк трейд практически не создает нагрузки на mysql. Актуальная статья для тех, кто использует ротацию, причем с большими базами.

В большинстве своем данная статья повторяет то что знает любой админ и написано множество раз в сотнях тысяч статей. Тут будет отмечено скорее в отношении конкретно SmartCJ.

Настройки Mysql - индексы

Вводные: данные базы хранятся на диске, работа с диском медленная (намного медленне чем с памятью). Дабы ускорить работу - придумали индексы. Если сильно упростить ситуацию: индекс это как оглавление в книге, когда вы знаете, что какие-то данные находятся в 3й главе например. Вы можете посомтреть оглавление, перейти сразу к 3й главе и уже искать там, тем самым избавившись от необходимости просматривать главы 1 и 2.

Вводная 2: базе есть таблицы, где хранятся данные галер\тумб. Условно тумба1 была показана 100 раз, кликнули по ней 20 раз и тп. Тк тумб и данных к ней много (не редкость базы по 500-600к тумб) то и данных получается довольно много (бывает и по гигу). Существует много типов хранения данных, но нас конкретно интерисуют 2 типа: MyISAM и InnoDB. MyISAM - дефолтный движек и он по дефолту он юзается в SmartCJ, но это устаревший движек, если можно так выразится.

В чем разница применительно к этой статье:

Основное, MyISAM хранит индекс и данные как 2 отдельных файлах, а InnoDB - как один файл и индекс встроен в этот файл. Как результат при запросе к таблице типа MyIsam, Mysql кеширует файл с индексами, поэтому крайне важно что бы сетинга key_buffer_size была достаточной, что б вместить туда все инедксы (они примерно 15% от размера данных). При запросе мускл смотрит по индексу с какого места начинать искать в датафайле и начинает искать. Этот датафайл лежит на диске и соответственно эта операция - медленная, и ее ускорением, насколько это возможно, занимается система (те обычный кеш операций с диском) с перменным успехом.

Если же мы используем InnoDB то, как уже было сказано выше, у него нет отдельного индексного файла, а он встроен в датафайл. Выглядит это так условно: в начале датафайлеа написано “в этой части у нас хранится инфа об ИД 1,2,3,4 и 5, следующуая часть начинается с 123784 байта этого файла”, mysql смотрит - 1-5 нам не надо, идем дальше к сл части и читаем начиная с позиции 123784 байт. Таким образом для InnoDB крайне важно держать в памяти весь датафайл и параметр отвечающий за это называется innodb_buffer_pool_size. Кеш самого mysql в отношении датафайлов эффективнее чем кеш самой системы и как результат, если датафайл полностью влезает в память - InnoDB в выборках обгоняет MyISAM на 25-35%. Однако как только файл перестает увлезать в память - у InnoDB начинается намного больше работы с диском, чем у MyIsam и как следствие он резко отстает от MyISAM.

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

И еще одно актуальное преимущество InnoDB перед MyISAM row lock VS table lock . Что это такое: например у нас есть таблица тех же тумб. В определенный момент крон пишет в таблицу обновленные ЦТР тумб, и пока он обновляет эти данные - лочится вся таблица тумб. Это значит что если обновремено в этот же момент пришел серфер и и для генерации страницы надо выбрать какие то данные из базы тумб, то скрипту придется ждать пока крон довыполняет обновление ЦТР. Серферу страница будет сгенерена медленее чем могла бы. У InnoDB - row lock, это значит если мы обновляем Цтр тумбы 1, то скрипт без проблем может в этот же момент получить данные о тумбе 2. Это сказывается на общей скорости работы сайта.

Исходя из того что:

  • неизвестно на какую версию Mysql
  • с каким настройками
  • с какой по размеру рабочей базой

будет поставлен скрипт , дефолтные таблицы - MyISAM, поскольку дефолтные настройки innodb очень маленькие.

Однако, если вы будете заниматься настрокой MySQL то сможете добиться 40% ускорения работы базы при условии того, что переведете ее на InnoDB. Однако не забывайте: как только датафайл перестанет влезать в память - скорость работы станет хуже, чем с MyIsam.

Одновные ньансы InnoDB:

  • innodb_buffer_pool_size - туда должен влезать весь датафайл (таблицы в InnoDB), те если он у вас 500 метров и их 5 штук то тут должно быть 2.5 ГИГА (конкретно эта цифтра - это размер всех активных rot_galleries + rot_gallery_data* + rot_gallery_stats таблиц ). Обратите внмиание что данные слейва rot_gallery_statsX храняться в базе мастера и соответственно конвертить эту таблицу надо там, а не на слейве.
  • конвертировать в innodb иметт смысл толкьо эти таблицы, остальные не слиьно нагружены конкурировать за память в пуле mysql будут.
  • innodb_additional_mem_pool_size - 64M
  • innodb_log_file_size - это даталог записей в базу, 64M
  • innodb_flush_log_at_trx_commit - поскольку innodb держит в памяти датафайл, то и обновления и дополнения идут в памяти, а потом пишутся на диск. Есть 2 варианта записи на диск - с обход системного кеша, когда данные точно сразу же записываются на диск и в системный кеш, когда данные пишутся в память кеша самой ОС, а ОС уже сама решает когда ей записать на диск. До дефолту innodb_flush_log_at_trx_commit = 1, это значит писать да диск сразу как только поступили данные в обход системного кеша. Это наиболее секурный вариант, но поскольку у нас не банковская система, то потеря данных добавленных за последние пару секунд для нас не страшна (при самом ужастном раскладе - добавляли галеры и последняя из добавленных пропала если упал сервак). Поэтому надо ставить или innodb_flush_log_at_trx_commit = 2 (запись в системный кеш сразу после добавления данных) или innodb_flush_log_at_trx_commit = 0 (запись в системный кеш как решит сам MySQL). Считается, что innodb_flush_log_at_trx_commit = 0 подходит для данной ситуации.

И для MyISAM и для InnoDB:

  • table_cache - когда MySQL начинаtn работать с таблицей, он должен ее открыть, те прочесть начало датафайла этой таблицы, что б поменять какая она, какие поля там есть и тп. Если вы видите в show processlist запросы в виде opening table - вероятно надо увеличить это значение. Вычисляется это так: например, у нас 10 одновременных подключений к базе где юзается 10 таблиц и таких баз с 10 подключениями тоже 10 - итого нам надо 10*10*10 = 1000. В целом 1024 хорошее значение.
  • max_heap_table_size = tmp_table_size = 256-512M При сложных запросах MySQL создает временные таблицы, и лучше если он это делает в памяти. Кроме того, рекомендуется создать в памяти виртуальный диск и указать его как tmp_dir для Mysql.
  • query_cache_size - смысл опции в следующем: например мы запрашиваем из базы: выдайте-ка нам инфу о тумбе ИД 12345, Mysql находит эти данные и кладет в свой внутренний кеш. В следующий раз, если приходит такой же запрос, он уже не лезет в датафайл, а выдает сразу же данные из кеша. Но есть 2 ньанса, которые делают эту опцию бесполезной: во-первых, если таблица меняется - весь кещ для данной таблицы сразу скидывается. Вероятность, того что мы еще раз запросим инфу о тумбе 12345, до того как изменится ЦТР какой-то другой тумбы крайне мала, тк ЦТР тумб меняется каждую минуту. Во-вторых, SmartCJ сам кеширует данные о тумбах в своем кеше. Таким образом, выделять доп память этой переменной имеет смысл только если у вас есть другие скрипты без кеша и тп. SmartCJ эта опция не нужна вообще.

Общие наблюдения

  • Имеет смысл использовать скрипты, которые подсказывают настройки, например MySQLTuner
  • если у вас выделенный серв для mysql - не имеет смысла брать его многоядерным, те 4 или 8 ядер более чем достаточно, дальше MySQL масштабируется плохо (актуально по крайней мере сейчас с версией MySQL 5.5) и самый большой прирост вы можете получить либо увеличением памяти дабы все влезло в innodb_buffer_pool_size либо переходом на SSD носители (или любой другой вариант ускорения дисковой системы)
  • убедитесь что на серваке, который должен выдерживать сотни тысяч посещений в сутки и миллионы запросов к базе, памяти хотя бы столько же, сколько на вашем настольном компьютере, где вы просто редактируете html :)

Mysql Table Engine : all in InnoDB

Несомтря на то, что написано выше конвертировать толкьо 3 таблицы, многие конвертирую вообще всю базу. Это не очень хорошая идея с точки зреня экономии памяти. Если остальные таблицы, например таблица с реферами, конвертированы в иннодб то при обновлении информации там (а это каждую минуту)эта информация попадает в пул, тем самым занимая там место. Более того учитывая что обновляется она каждую минуту - mysql может посчитать что это достаточная интенсивность и держать там ее вытеснив какую то часть rot_*. Но при этом работа в rot_* идет постоянно, а реферы админ смотрит хорошо если раз в сутки.

Таким образом для экономии имеет смысл конвертировать только таблицы rot_* , а для еще бОльшей - rot_galleries, rot_gallery_stats* and rot_gallery_data*.

ru/mysql_tunning.txt · Last modified: 2014/02/18 12:49 by admin