MySQL の総テーブル数に比例してメモリの使用量が増大する症状の対応

MySQL 5.1/5.5 では InnoDB を利用した際に、総テーブル数に比例して増大していくという症状が発生します。 これは innodb_buffer_pool_size の制限項目とは別に割り当てられる領域となるので、 思わぬところでメモリが多く消費されてしまい場合によっては Swap が発生してしまうといった懸念がありました。

show engine innodb status でメモリの状況を確認することができます。

----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 36487168; in additional pool allocated 0
Dictionary memory allocated 378360
Buffer pool size   2176
Free buffers       1192
Database pages     984
Old database pages 383
Modified db pages  0
Pending reads 0
Pending writes: LRU 0, flush list 0 single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 984, created 0, written 113
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s

Dictionary memory allocated の箇所、これが Dictionary cache の割り当てにあたり、 具体的には InnoDB のテーブルを開くとこの値が増えていきます。

この症状については、以下の記事にグラフとして載っていました。
http://mysqlmaniac.com/2012/how-having-many-tables-affects-mysql-memory-usage/

なお、対処法となりますが、2つ挙げられています。

  • ・MySQL 5.5 Percona を利用して、innodb_dict_size_limit を設定することにより、Dictionary memory の上限値が設定されます。
  • ・MySQL 5.6 を利用します。

いずれの場合も innodb_file_per_table を OFF にすることによりメモリ使用量は定量になるようです。

MySQL 5.6 については、innodb_dict_size_limit に相当する設定を、table_definition_cache で行うようです。 http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_table_definition_cache