私のcentos 6.3サーバーには、MySQL 5.5.33データベースがあります。
これには17個のテーブル(15個のInnoDB、2個のMyISAM)と合計670万行のレコードがあります。スキーマをリファクタリングし、遅いログのインデックスを追加しました。私の平均クエリ時間は20〜30ミリ秒です。そして、私のデータベースはうまく機能します。
しかし、3時間ごとに実行されるcronクエリがいくつかあります。インデックスを使用せず、実行速度が非常に遅く、すべてのクエリが約1500〜2000ミリ秒実行されます。新しいインデックスを追加する予定はありません。その場合、多くのインデックスを追加する必要があり、クエリが実行されることは非常にまれです。
データベースサーバーを再起動すると、-通常-スワップがゼロになります。しばらくするとスワッピングが徐々に大きくなっていきます。 13日後、MySQLの650MBのスワップを取得します。このスワッピングの原因を見つけて、パフォーマンスグレードなしでスワッピングを減らしたいと思います。
原因がcronクエリであるか、その他の原因でこのスワップサイズが発生していることを確認します。
私のtop
結果:
top - 13:33:01 up 13 days, 11:04, 1 user, load average: 0.77, 1.02, 1.07
Tasks: 148 total, 1 running, 147 sleeping, 0 stopped, 0 zombie
Cpu(s): 27.4%us, 5.3%sy, 0.0%ni, 59.1%id, 7.8%wa, 0.0%hi, 0.3%si, 0.0%st
Mem: 1020564k total, 854184k used, 166380k free, 73040k buffers
Swap: 2097144k total, 643036k used, 1454108k free, 94000k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ SWAP COMMAND
9573 mysql 20 0 2336m 328m 3668 S 7.3 33.0 349:14.25 554m mysqld
15347 examplecom 20 0 219m 32m 10m S 2.7 3.2 0:02.66 0 php-cgi
15343 examplecom 20 0 215m 28m 10m S 10.0 2.9 0:05.80 0 php-cgi
15348 examplecom 20 0 215m 28m 10m S 12.3 2.8 0:03.62 0 php-cgi
15346 examplecom 20 0 215m 28m 10m S 9.6 2.8 0:06.39 0 php-cgi
15350 examplecom 20 0 212m 25m 10m S 10.0 2.6 0:02.19 0 php-cgi
15345 examplecom 20 0 211m 24m 10m S 6.6 2.5 0:04.28 0 php-cgi
15349 examplecom 20 0 209m 22m 10m S 5.3 2.2 0:02.66 0 php-cgi
12771 Apache 20 0 334m 5304 2396 S 0.0 0.5 0:02.53 10m httpd
12763 Apache 20 0 335m 5224 2232 S 0.3 0.5 0:02.33 11m httpd
編集:私は2日前にmysqlサーバーを再起動したので、現在スワップは少ないです。しかし、時間の経過とともに、それは再び大きくなります。 top
を作成すると、次のようになります。
top - 23:30:46 up 15 days, 21:01, 1 user, load average: 0.35, 0.42, 0.42
Mem: 1020564k total, 931052k used, 89512k free, 76412k buffers
Swap: 2097144k total, 280528k used, 1816616k free, 233560k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ SWAP COMMAND
23088 mysql 20 0 1922m 311m 3440 S 1.0 31.3 50:04.53 143m mysqld
10081 examplecom 20 0 216m 28m 10m S 4.0 2.8 0:01.67 0 php-cgi
10069 examplecom 20 0 215m 27m 10m S 3.3 2.7 0:04.81 0 php-cgi
10070 examplecom 20 0 215m 26m 10m S 8.3 2.7 0:04.75 0 php-cgi
10062 examplecom 20 0 215m 26m 10m S 6.0 2.7 0:06.26 0 php-cgi
10060 examplecom 20 0 214m 25m 10m S 5.3 2.6 0:07.51 0 php-cgi
10074 examplecom 20 0 214m 25m 10m S 6.6 2.6 0:03.01 0 php-cgi
10080 examplecom 20 0 212m 23m 10m S 6.0 2.4 0:01.58 0 php-cgi
私が作るときfree -m
私はこれを得ます:
total used free shared buffers cached
Mem: 996 927 68 0 76 219
-/+ buffers/cache: 631 364
Swap: 2047 273 1774
ぼくの /etc/my.cnf
ファイルの内容:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
symbolic-links=0
skip-name-resolve
slow_query_log=ON
long_query_time=1.2
innodb_file_per_table
max_allowed_packet=32M
thread_stack=256K
max_allowed_packet=32M
thread_stack=256K
max_connect_errors=100000000
max_connections=600
key_buffer=256M
sort_buffer_size=2M
read_buffer_size=2M
read_rnd_buffer_size=2M
thread_cache_size = 8
tmp_table_size=128M
max_heap_table_size=128M
query_cache_size = 209715200
query_cache_limit = 52428800
join_buffer_size=4M
table_cache=2400
low_priority_updates=1
tmpdir = /var/tmp
query_cache_type = 1
innodb_buffer_pool_size=256M
innodb_additional_mem_pool_size=512K
innodb_log_buffer_size=500K
innodb_thread_concurrency=8
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
メモリを過剰に割り当てているようです。より大きなセッションバッファー(tmp_table_size=128M, max_heap_table_size=128M
など)とともに、比較的多数の接続(600)を許可します。したがって、最悪の場合、600個の並列セッションすべてがMEMORY
エンジンの一時テーブルに許可された128Mを使い果たすと、600x128M= 77G
メモリが必要になります。ただし、sort_buffer_size=2M
を使用しても1.2 GBが必要ですが、1 GBしかありません。
スワップが使用されていることは、この場合の驚きではありません。ステータス変数Max_used_connections
をチェックして、最大600の接続を使用しているかどうかを確認し、max_connections
変数を減らします。ステータス変数Created_tmp_disk_tables
およびCreated_tmp_tables
を確認してください。tmp_table_size
が劇的に増加しなくなるまで、Created_tmp_disk_tables
を安全に減らすことができます。
また、カーネルオプションvm.swappiness
が高すぎないかどうか(100など)を確認して、Linuxがより早くスワップを開始し、メモリが不足した場合により積極的にスワップするようにします。