概要
MySQL 5.6 までは、MySQL を起動する際にパフォーマンススキーマが使用するメモリーがあらかじめ割り当てられます。
以前 実メモリー 512 MB のサーバーで max_connections=3000 を設定して起動したところ、OOM Killer(Out of Memory Killer) にプロセスが kill されてしまったことがあるので、パフォーマンススキーマが確保するメモリー量について調査を行いました。
検証環境
- CentOS 6.8 (CPU:1コア、 メモリー:1 GB)
- MySQL 5.6.35
内容
まず、パフォーマンススキーマの構成情報については、以下のコマンドで確認することが可能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
mysql> SHOW GLOBAL VARIABLES LIKE 'performance_schema%'; +--------------------------------------------------------+-------+ | Variable_name | Value | +--------------------------------------------------------+-------+ | performance_schema | OFF | | performance_schema_accounts_size | -1 | | performance_schema_digests_size | -1 | | performance_schema_events_stages_history_long_size | -1 | | performance_schema_events_stages_history_size | -1 | | performance_schema_events_statements_history_long_size | -1 | | performance_schema_events_statements_history_size | -1 | | performance_schema_events_waits_history_long_size | -1 | | performance_schema_events_waits_history_size | -1 | | performance_schema_hosts_size | -1 | | performance_schema_max_cond_classes | 80 | | performance_schema_max_cond_instances | -1 | | performance_schema_max_digest_length | 1024 | | performance_schema_max_file_classes | 50 | | performance_schema_max_file_handles | 32768 | | performance_schema_max_file_instances | -1 | | performance_schema_max_mutex_classes | 200 | | performance_schema_max_mutex_instances | -1 | | performance_schema_max_rwlock_classes | 40 | | performance_schema_max_rwlock_instances | -1 | | performance_schema_max_socket_classes | 10 | | performance_schema_max_socket_instances | -1 | | performance_schema_max_stage_classes | 150 | | performance_schema_max_statement_classes | 168 | | performance_schema_max_table_handles | -1 | | performance_schema_max_table_instances | -1 | | performance_schema_max_thread_classes | 50 | | performance_schema_max_thread_instances | -1 | | performance_schema_session_connect_attrs_size | -1 | | performance_schema_setup_actors_size | 100 | | performance_schema_setup_objects_size | 100 | | performance_schema_users_size | -1 | +--------------------------------------------------------+-------+ 32 rows in set (0.00 sec) |
※これはパフォーマンススキーマを無効にした状態の結果です。
このうち、値が -1 となっているものについては、起動時にパフォーマンススキーマが有効になっている場合、次のシステム変数の値に基づいてその値を設定する方法が判断されます。
- max_connections
- open_files_limit
- table_definition_cache
- table_open_cache
また、実際にパフォーマンススキーマが確保しているメモリーは、以下の値によって確認することが出来ます。
1 2 3 4 5 6 7 8 |
mysql> SHOW ENGINE PERFORMANCE_SCHEMA STATUS; +--------------------+--------------------------------------------------------------+-----------+ | Type | Name | Status | +--------------------+--------------------------------------------------------------+-----------+ (...) | performance_schema | performance_schema.memory | 423563584 | +--------------------+--------------------------------------------------------------+-----------+ 167 rows in set (0.00 sec) |
このシステム変数によるメモリー確保量を比較してみた結果は以下の通りでした。
パフォーマンススキーマのパラメータ値(performance_schema%)を決める計算式については、storage/perfschema/pfs_autosize.cc に詳細が記載されています。
なお上記のシステム変数の値に応じて、あらかじめ次のようなサイジングが内部的に行われています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
PFS_sizing_data *estimate_hints(PFS_global_param *param) { if ((param->m_hints.m_max_connections <= MAX_CONNECTIONS_DEFAULT) && (param->m_hints.m_table_definition_cache <= TABLE_DEF_CACHE_DEFAULT) && (param->m_hints.m_table_open_cache <= TABLE_OPEN_CACHE_DEFAULT)) { /* The my.cnf used is either unchanged, or lower than factory defaults. */ return & small_data; } if ((param->m_hints.m_max_connections <= MAX_CONNECTIONS_DEFAULT * 2) && (param->m_hints.m_table_definition_cache <= TABLE_DEF_CACHE_DEFAULT * 2) && (param->m_hints.m_table_open_cache <= TABLE_OPEN_CACHE_DEFAULT * 2)) { /* Some defaults have been increased, to "moderate" values. */ return & medium_data; } /* Looks like a server in production. */ return & large_data; } |
各デフォルト値
1 2 3 |
#define MAX_CONNECTIONS_DEFAULT 151 #define TABLE_DEF_CACHE_DEFAULT 400 #define TABLE_OPEN_CACHE_DEFAULT 2000 |
ここで、TABLE_DEF_CACHE_DEFAULT の値は MySQL 5.6.35 のデフォルト値の 1400 (400+(table_open_cache/2))ではなく、MySQL 5.6.7 以前の 400 として定義されているため、上記の表は全て large_data としてサイジングされてしまっていることに注意してください。
この結果を受けて、改めて各サイズ毎に計測し直したのが以下の表になります。
サイズの違いによって、パフォーマンススキーマのメモリー確保量が大きく変化していることがわかります。
なお、この結果を基に、各サイズにおける、max_connections 毎のメモリー増加量を概算すると、以下の通りでした。
サイズ | max_connections 増加毎のメモリー増加量(KB) |
---|---|
small | 78.23 |
medium | 123.37 |
large | 173.75 |
※増加分の他に、small で約 10 ~ 30 MB、medium で約 90 ~ 100 MB、large で約 400 MB 程のメモリーが確保されます。
※この値は今回の結果に基づいて計算したものであり、実際のメモリー確保量は設定値によって変化するので注意してください。
まとめ
- MySQL 5.6.35 のデフォルト設定(large_data)で起動すると、パフォーマンススキーマは 400 MB 程度のメモリーを確保します。
- max_connections <= 151 かつ table_definition_cache <= 400 かつ table_open_cache <= 2000 以下に設定(small_data)していれば、パフォーマンススキーマの使用メモリーを 50 MB 程度に抑えられます。
- メモリーに余裕のない環境の場合、MySQL 5.6 まではパフォーマンススキーマを無効にしておくのが無難です。
参考URL
22.2.2 パフォーマンススキーマ起動構成
Bug #68514 5.6 huge memory usage with max_connections parameter