<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>mysyslog.ru &#187; dba</title>
	<atom:link href="http://mysyslog.ru/posts/tag/dba/feed" rel="self" type="application/rss+xml" />
	<link>http://mysyslog.ru</link>
	<description>Всякая IT всячина</description>
	<lastBuildDate>Sat, 17 Mar 2012 17:39:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Настройка производительности MySQL (MyISAM)</title>
		<link>http://mysyslog.ru/posts/52</link>
		<comments>http://mysyslog.ru/posts/52#comments</comments>
		<pubDate>Sat, 03 Jan 2009 12:51:32 +0000</pubDate>
		<dc:creator>constantine.malov</dc:creator>
				<category><![CDATA[Советы]]></category>
		<category><![CDATA[dba]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://mysyslog.ru/?p=52</guid>
		<description><![CDATA[
В свое время я достаточно долго искал в интернете внятное описание тюнинга производительности mysql и ничего подходящего не находил. На mysql.com главы документации о производительности носят скорее декларативный характер &#8211; &#8220;Сделайте так, и все будет хорошо&#8221; &#8211; без описание почему именно такие значения нужно выставить. Сейчас ситуация несколько меняется, появляются статьи о правильной настройке с [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" title="mysql" src="http://mysql.com/common/logos/logo_mysql_sun_a.gif" alt="" width="114" height="68" /><br />
В свое время я достаточно долго искал в интернете внятное описание тюнинга производительности mysql и ничего подходящего не находил. На <a href="http://mysql.com">mysql.com</a> главы документации о производительности носят скорее декларативный характер &#8211; &#8220;Сделайте так, и все будет хорошо&#8221; &#8211; без описание почему именно такие значения нужно выставить. Сейчас ситуация несколько меняется, появляются статьи о правильной настройке с объяснениями, похоже в основном благодаря книге <a href="http://www.amazon.com/High-Performance-MySQL-Optimization-Replication/dp/0596101716/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1230980722&amp;sr=8-1">High Performance MySQL</a>. Этой публикацией я открываю небольшой цикл статей, призванных помочь системным администраторам и web-мастерам настраивать mysql.</p>
<p><span id="more-52"></span><br />
Один из самых важных параметров с точки производительности MyISAM &#8211; key_buffer_size. Во всех рекомендациях советуют отдавать под него 30-40% процентов физической памяти. Правда почти нигде не рассказывается почему именно так. Попробую ответить на этот вопрос.<br />
Переменная key_buffer_size определяет какой размер индексов можно поместить в оперативную память (кеш). MyISAM хранит индексы в отдельных файлах с расширением .MYI, т.е. для того, чтобы воспользоваться индексами mysql должна открыть и прочитать один из файлов .MYI. Нужно напомнит, что IO операции с дисками крайне медленны по сравнению, например, с оперативной памятью. Потому снижение числа дисковых IO операций &#8211; основная стратегия повышения производительности в любом высоконагруженном приложении, не только в СУБД. Mysql, следуя стратегии уменьшения IO операций, прочитав индекс из файла, помещает полученное значение в оперативную память. В случае если этот индекс потребуется еще раз, mysql его считает уже из кеша, что значительно быстрее. Если память под индексы достигла размера key_buffer_size, то mysql удалит старые данные из кеша. Т.е. если удаленные данные опять потребуются, их придется читать с диска. Из этого легко сделать вывод, что идеальным вариантом будет поместить все индексы в память. Но сколько памяти под индексы нужно? Индексы хранятся в файлах размер которых можно подсчитать. Конечно же нужно помнить, что размер индексов будет меняться во времени.<br />
Подсчитать размер файлов индексов очень просто. Для этого нужно перебраться в каталог со всеми базами. Подсмотреть имя каталога можно так:</p>
<pre lang="sql">mysql&gt; show variables like 'datadir';</pre>
<p>Далее выполняем du:</p>
<pre lang="bach"># cd /var/lib/mysql/
# du -ch */*.MYI
...
54M    total</pre>
<p>Т.е. сейчас под индексы хватит 64 Мб с небольшим запасом на рост. Это очень хороший результат, так как все индексы без проблем помещаются в память. 64М легко выделить почти на любой системе. Как же быть с базами, у которых индексы занимают несколько Гб? На 32х битных системах в этом плане все совсем плохо из-за ограничения по памяти в 4Гб. Для таких систем может пригодиться система разделения на горячий и холодный кеш. Представьте ситуацию, сервер выполнил редкий запрос, который потребовал считать достаточно много индексов с диска. Для их хранения пришлось вытеснить из памяти индексы других запросов, которые могут выполняться куда чаще. В результате, серверу пришлось прочитать с диска индексы для этого редкого запроса, да еще потом считать с диска все вытесненные им из кеша индексы&#8230;<br />
Чтобы избежать такой ситуации можно разделить кеш на &#8220;горячий&#8221; и &#8220;холодный&#8221;. При первом чтении индекса он попадает в холодный кеш. Если индекс используется еще раз, то он перемещается в горячий кеш. Если памяти не хватает, то вытесняются только те значения индексов, которые находятся в холодной части кеша. Т.е. часто используемые индексы остаются в памяти. Соотношение между горячим и холодным кешами задается переменной key_cache_division_limit. По умолчанию, key_cache_division_limit = 100, т.е. существует только горячий кеш.<br />
На 64x битной системе казалось бы проблемы с памятью под индексы не должно быть. Главное, чтобы было достаточно физической памяти. Но в mysql до версии 5.1 размер кеша ограничен 4Гб. Похоже это баг, который судя по всему так и не исправили в боле ранних версиях. Вы знаете много людей, перешедших в продакшене на mysql 5.1? Я нет. Многие продолжают использовать 4.1. Обойти это ограничение на 64х битных машинах можно. Для этого есть именованные индексы. Можно создать отдельные индексы для каких-то конкретных таблиц таким образом суммарный объем памяти под индексы быдет состоять из общего буфера и именованных кешей, которые в сумме могут быть больше чем 4Гб. Для создания именованного кеша key_buffer_1 нужно отредактировать my.cnf, добавив в него строчку:</p>
<pre lang="bash">key_buffer_1.key_buffer_size = "32M"</pre>
<p>После этого нужно определить для каких таблиц будет использоваться этот кеш, в нашем примере это таблицы t1 и t2:</p>
<pre lang="sql">CACHE INDEX t1,t2 IN key_buffer_1;</pre>
<p>Разделение на несколько кешей помимо основного буфера позволяет решить проблему с вытеснением индексов из памяти. Можно создать отдельные буфера в памяти для наиболее часто используемых таблиц.<br />
Есть еще одна хитрость, любой индекс перед тем как попасть в кеш должен быть считан с диска, что может быть совершенно лишним в момент &#8220;боевой&#8221; работы сервера. Этого можно избежать, загрузив все индексы в момент старта сервера. Главное, чтобы памяти хватило. Делается это командой:</p>
<pre lang="sql"> LOAD INDEX INTO CACHE t1,t2</pre>
<p>Как понять что все плохо? Т.е. плохо в данном случае &#8211; это когда слишком много чтений ключей с диска. Данные о чтении индексов из памяти или с дисков можно посмотреть так:</p>
<pre lang="sql">mysql&gt; show global status like 'key_read%';
Variable_name Value

Key_read_requests 132
Key_reads 3</pre>
<p>Key_read_requests &#8211; чтения из памяти.<br />
Key_reads &#8211; чтение с дисков<br />
Можно использовать эту формулу, чтобы определить процент запросов к дискам: <code>100 - ( Key_read_requests * 100) / ( Key_reads + Key_read_requests )</code><br />
Чем ближе это значение к 0, тем лучше для производительности. Но с этими данными нежно обращаться осторожно, как и с любыми относительными вычислениями. 0,1 процента запросов к диску на разных системах могут очень сильно отличаться по своей сути. На одном сервер это будет одно обращение в час, а на другом десятки и сотни в секунду.<br />
Потому нужно отслеживать и абсолютные значения. Хорошим вариантом будет отслеживать число запросов к дискам в секунду в моменты пиковой нагрузки на сервер. Для этого нужно посмотреть значение Key_reads в разные моменты времени. Пусть пиковыми часами нагрузки у нас является промежуток между 12тью и 15 часами дня. Тогда нужно замерить значение  Key_reads в 12 часов, и еще раз в 15 часов. Их разница поделенная на число секунд в трех часах даст значение обращений к дискам в секунду. Далее полученное число можно сравнить производительностью дисков, но это уже совсем другая история.</p>
<p>&#8211;<br />
Для подготовки этой стати использовались материалы из книги <a href="http://www.amazon.com/High-Performance-MySQL-Optimization-Replication/dp/0596101716/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1230980722&amp;sr=8-1">High Performance MySQL</a>, сайтов <a href="http://sqlinfo.ru/articles/info/3.html">sqlinfo.ru</a> и <a href="http://mysqlperformanceblog.com">mysqlperformanceblog.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mysyslog.ru/posts/52/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

