メモ > サーバ > 構築: チューニング > MySQL チューニング
MySQL チューニング
※マシンの搭載メモリをもとに設定を調整する
※MySQLの設定ファイル my.cnf を編集してチューニングする
※MySQLのメモリ設定には、大きく分けて以下の2つがある
グローバルバッファ ... mysqld全体で確保するメモリ
スレッドバッファ ... コネクションごとに確保するメモリ
MySQL 初めてのチューニング
http://www.slideshare.net/Craftworks/my-sql-6113813
MySQLのmy.cnfファイルサンプル
http://time-complexity.blogspot.jp/2013/10/mysqlmycnf.html
MySQLの設定ファイル my.cnf をgithubにて公開しました & チューニングポイントの紹介
http://blog.nomadscafe.jp/2012/10/mysql-mycnf-github.html
/etc/my.cnf で設定できる
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
character-set-server = utf8
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
以下のように設定を調整(WebサーバとDBサーバは共通で、搭載メモリは1Gとする)
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
character-set-server = utf8
max_connections = 65 #最大同時接続数
#サーバに合わせて設定する必要がある
#SHOW GLOBAL VARIABLES like '%connections%'; で Max_used_connections を参考にするといい(MySQLを起動してからの最大同時接続数)
#負荷テストをすると必然的に上がってしまう?
#グローバルバッファ
innodb_buffer_pool_size = 512M #InnoDBのインデックスやレコードをキャッシュする領域。DB専用サーバなら全体の7〜8割程度、そうでないなら5割程度を割り当てる
innodb_additional_mem_pool_size = 8M #InnoDBのテーブル定義情報を格納する領域。それほど気にする必要は無い。エラーログに警告が出たら増やせばいい
innodb_log_buffer_size = 8M #InnoDBのトランザクションを管理する領域。大抵は8M、多くても64Mで十分。他のパラメータにメモリを渡すほうが得策
key_buffer_size = 8M #MyISAMで索引検索をする際にインデックス情報を格納する領域。MyISAMを使うなら256M程度にする。DB専用サーバなら全体の25%程度割り当てても問題ない
query_cache_size = 128M #SELECT文の実行結果をキャッシュする領域。100〜200Mくらいが推奨されているようだが、128M以上には設定しない方がいい。INSERT, UPDATE, DELETEが頻繁に起こるサーバーでは大きく設定する必要はない
#スレッドバッファ
myisam_sort_buffer_size = 1M #MyISAMでインデックスのソートに使われる領域。それほど大きくする必要は無い。MyISAMを使うなら8M程度でいい
sort_buffer_size = 2M #ソートの際に利用される領域。ORDER BY や GROUP BY を多用するなら多めにするといい。スレッドバッファなので2M以上には設定しない方がいい
read_rnd_buffer_size = 1M #ソート後にレコードを読み込む際に利用される領域。ディスクI/Oが減るので、ORDER BY の性能向上が期待できる。ORDER BY を多用するなら多めにするといい。1〜2Mくらいが妥当
join_buffer_size = 128K #インデックスを使用しないテーブルの結合に使われる領域。インデックスを用いないテーブル結合は避けるべきなので、大きくする必要は無い
read_buffer_size = 128K #テーブルスキャンの際に利用される領域。インデックスを用いないクエリは避けるべきなので、大きくする必要は無い
#メモリ以外の設定
innodb_log_file_size = 128M #InnoDBの更新ログを記録するディスク上のファイル。innodb_buffer_pool_sizeを大きくしたら合わせて大きくする。1M以上に設定する。32bitマシンの場合は4G以下に設定する
#innodb_log_file_size * innodb_log_files_in_group(デフォルト2) の値が innodb_buffer_pool_size を超えてはいけない
table_open_cache = 1024 #開いたテーブルのファイルポインタを格納する領域。「同時接続数×テーブル数」が最低限必要。1024〜2048が一般的。MyISAMでは1テーブルにつき2つ消費
thread_cache_size = 20 #スレッドをキャッシュにいくつ保存しておくのか決める。実際の稼働状況を把握しないと何とも言えない。max_connectionsの1/3ぐらいか
wait_timeout = 10 #接続したクライアントが何もせずにいるとき、接続を切断する時間。単位は秒でDefaultは28800秒(8時間)で、かなり大きい値
#Webでの接続の場合、Webサーバのタイムアウト時間と同じでいい?
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
設定内容の妥当性を確認する
stack_sizeはコネクションごとに確保される領域。バイナリパッケージの種類によっては変更できないものもあり、256K固定と考えて良さそう
64bitマシンの場合、以下の式が搭載メモリの8〜9割程度になるように(DB専用サーバでないなら7割程度にする)
32bitマシンの場合、以下の式が2GBに近いもしくは上回っていると危険(32bitマシンではソフトに割り当てられるメモリは2Gまでだから?)
innodb_buffer_pool_size + key_buffer_size + (max_connections * (sort_buffer_size + read_buffer_size + read_rnd_buffer_size)) + (max_connections * stack_size)
512M 8M 65 2M 128K 1M 65 256K
520M + ( 65 * 3.2M ) + 65 256K
520M + ( 65 * 3.2M ) + 17M
520M + 210M + 17M
747M
上の設定だと、最大747MのメモリがMySQLに割り当てられることになる
スペック(メモリ)が変われば innodb_buffer_pool_size と innodb_log_file_size の値を変更し、それに合わせて max_connections も変更する
他の値も一通り見直す
メモリ1Gのサーバなら、以下くらいに抑えてもいいかも?実験中
innodb_buffer_pool_size + key_buffer_size + (max_connections * (sort_buffer_size + read_buffer_size + read_rnd_buffer_size)) + (max_connections * stack_size)
300M 8M 30 2M 128K 1M 30 256K
310M + ( 30 * 3.2M ) + 30 256K
310M + ( 30 * 3.2M ) + 8M
310M + 96M + 8M
414M
MySQLからの結果によってページを出力する場合、Apache的に同時接続数80に耐えられたとしても
max_connectionsが65なら同時接続数65までにしか対応できないので注意
MySQLのチューニング
http://nohohonlab.exblog.jp/i2
一旦ApacheのMaxClientsと同じ値で良さそう
その設定でメモリ不足になるなど問題があるようなら、ApacheのMaxClients側の値を減らす
wait_timeoutも設定する?その場合、ApacheのTimeoutと同じ値でいい?
チューニングではないが、以下の値も明示的に設定しておくといいかも?
max_allowed_packet
インポート時に「MySQL server has gone away」が発生したときの対処
http://company.nankikumano.jp/contents/tech_info/104/
■設定変更時のエラー対策
MySQLのinnodb_log_file_sizeを設定して再起動(service mysqld restart)しようとするとエラーになる
# service mysqld restart
mysqld を停止中: [ OK ]
MySQL Daemon failed to start.
mysqld を起動中: [失敗]
InnoDBは my.cnf で指定された innodb_log_file_size の値と実際のログファイルのサイズが異なるとエラーにするらしい
ただし、そのファイルが存在しなかった場合は再作成してくれるらしい
よって以下の手順で変更する
mysql> SET GLOBAL innodb_fast_shutdown=0;
# service mysqld stop
# mv /var/lib/mysql/ib_logfile* /tmp
# vi /etc/my.cnf
# service mysqld start
これなら大丈夫だった
MySQLのinnodb_log_file_sizeを変更したらMySQLが起動しなくなった - /dev/null
http://gitpub.hatenablog.com/entry/2013/08/02/001600
innodb_log_file_size のサイズを変更するには - Enjoi Blog
http://blog.enjoitech.com/article/196