Memo

メモ > サーバ > 構築: チューニング > 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

Advertisement