MySQLがメモリを解放しない


8

MySQLは、大きな挿入または選択ステートメントが実行された後、テーブル全体をキャッシュ(テーブルサイズ=〜20GB)に保持したいようです。現在、私のinnodbバッファープールは20GBです。合計RAMは32GBです。メモリ使用量とinnodbステータスからの出力、およびmysqltunerからの出力を提供します。過去数日間、私は気が狂っている。助けてください!フィードバックに感謝します。さらに情報が必要な場合はお知らせください。

また、「FLUSH TABLES」を実行すると、メモリ内で閉じて再度開きます。少なくとも私はそれが起こっていると思います。一連の挿入を実行する前のinnodbの現在のメモリステータスは次のとおりです。

----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 21978152960; in additional pool allocated 0
Dictionary memory allocated 6006471
Buffer pool size   1310719
Free buffers       347984
Database pages     936740
Old database pages 345808
Modified db pages  0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 78031, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 551887, created 384853, written 4733512
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
LRU len: 936740, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]

mysqldのメモリ使用率:60.9%

挿入後のmysqldパーセントメモリ使用量(1 milレコード):63.3%

さらに挿入した後(3 milレコード):70.2%

それは約62.5%でキャップアウトすべきではありませんか?(20 / 32GB)合計RAM?

私のMEMの使用状況を上からソートした出力:

top - 14:30:56 up 23:25,  3 users,  load average: 3.63, 2.31, 1.91
Tasks: 208 total,   4 running, 204 sleeping,   0 stopped,   0 zombie
Cpu(s): 96.0%us,  3.0%sy,  0.0%ni,  0.0%id,  1.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  28821396k total, 28609868k used,   211528k free,   138696k buffers
Swap: 33554428k total,    30256k used, 33524172k free,  1208184k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 1228 mysql     20   0 25.1g  19g 5512 S   31 70.2  62:01.10 mysqld

これらの挿入が実行された後のinnodbメモリ出力は次のとおりです。

----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 21978152960; in additional pool allocated 0
Dictionary memory allocated 6006471
Buffer pool size   1310719
Free buffers       271419
Database pages     1011886
Old database pages 373510
Modified db pages  4262
Pending reads 1
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 82521, not young 0
7.08 youngs/s, 0.00 non-youngs/s
Pages read 585218, created 426667, written 5192189
24.08 reads/s, 53.08 creates/s, 1135.07 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 1011886, unzip_LRU len: 0
I/O sum[0]:cur[266], unzip sum[0]:cur[0]

innodbステータスによると、割り当てられたメモリの合計は同じですが、私のOS(仮想Ubuntuサーバー12.04)はそれよりも多くのメモリ使用量を報告しています。メモリ使用量は同じままで、ここではメモリを「解放」しないMySQLサービスとして定義しています。助言がありますか?

mysqltuner.plからの出力:

-------- Storage Engine Statistics -------------------------------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MRG_MYISAM
[--] Data in MyISAM tables: 226M (Tables: 287)
[--] Data in InnoDB tables: 33G (Tables: 1000)
[--] Data in PERFORMANCE_SCHEMA tables: 0B (Tables: 17)
[--] Data in MEMORY tables: 0B (Tables: 1)
[!!] Total fragmented tables: 959

-------- Security Recommendations  -------------------------------------------
[OK] All database users have passwords assigned

-------- Performance Metrics -------------------------------------------------
[--] Up for: 23h 14m 27s (1M q [14.603 qps], 6K conn, TX: 16B, RX: 1B)
[--] Reads / Writes: 46% / 54%
[--] Total buffers: 22.2G global + 2.7M per thread (151 max threads)
[OK] Maximum possible memory usage: 22.6G (82% of installed RAM)
[OK] Slow queries: 0% (6/1M)
[OK] Highest usage of available connections: 6% (10/151)
[OK] Key buffer size / total MyISAM indexes: 2.0G/58.7M
[OK] Key buffer hit rate: 100.0% (216M cached / 38K reads)
[OK] Query cache efficiency: 81.2% (799K cached / 984K selects)
[!!] Query cache prunes per day: 5561
[OK] Sorts requiring temporary tables: 4% (819 temp sorts / 16K sorts)
[!!] Temporary tables created on disk: 27% (6K on disk / 22K total)
[OK] Thread cache hit rate: 99% (11 created / 6K connections)
[!!] Table cache hit rate: 0% (97 open / 10K opened)
[OK] Open file limit used: 12% (129/1K)
[OK] Table locks acquired immediately: 99% (433K immediate / 433K locks)
[!!] InnoDB  buffer pool / data size: 20.0G/33.6G
[OK] InnoDB log waits: 0
-------- Recommendations -----------------------------------------------------
General recommendations:
    Run OPTIMIZE TABLE to defragment tables for better performance
    MySQL started within last 24 hours - recommendations may be inaccurate
    Enable the slow query log to troubleshoot bad queries
    When making adjustments, make tmp_table_size/max_heap_table_size equal
    Reduce your SELECT DISTINCT queries without LIMIT clauses
    Increase table_cache gradually to avoid file descriptor limits
    Read this before increasing table_cache over 64: http://bit.ly/1mi7c4C
Variables to adjust:
    query_cache_size (> 128M)
    tmp_table_size (> 128M)
    max_heap_table_size (> 16M)
    table_cache (> 431)
    innodb_buffer_pool_size (>= 33G)

回答:


8

まず、InnoDBアーキテクチャを見てみましょう(Percona CTP Vadim Tkachenko提供)

InnoDBアーキテクチャ

InnoDB

バッファプールのステータスは次のとおりです

バッファープールサイズ1310719

これがページのバッファサイズです。各ページは16Kです。結局、20G-16Kになります。

次の点に注意してください。InnoDBバッファープールにデータをプッシュしました。何が変わったの?

Buffer pool size   1310719 
Free buffers       271419 (It was 347984)
Database pages     1011886 (Is was 936740)
Old database pages 373510 (It was 345808)
Modified db pages  4262 (It was 0)

また、ページ内のバッファプールサイズの違いにも注意してください。

1310719(バッファプールサイズ)-1011886(データベースページ)= 298833

それは298833 InnoDBページです。それはどのくらいのスペースですか?

mysql> select FORMAT(((1310719  - 1011886) * 16384) / power(1024,3),3) SpaceUsed;
+-----------+
| SpaceUsed |
+-----------+
| 4.560     |
+-----------+

それは4.56GBです。そのスペースは、InnoDBバッファープール(別名変更バッファー)挿入バッファーセクションに使用されます。これは、システムテーブルスペースファイル(すべてがとして認識されるようになったibdata1)への一意でないインデックスへの変更を軽減するために使用されます。

InnoDBストレージエンジンはバッファプールの内部を管理しています。したがって、InnoDBがRAMの62.5%を超えることはありません。さらに、バッファープールのRAMが返されることはありません。

RAMの70.2%はどこから来るのですか?

mysqltuner.plこれらの行の出力を振り返ってください

[OK] Maximum possible memory usage: 22.6G (82% of installed RAM)
Key buffer size / total MyISAM indexes: 2.0G/58.7M
[--] Total buffers: 22.2G global + 2.7M per thread (151 max threads)

mysqldには、RAMを割り当てる3つの主要な方法があります。

DB接続に小さなスパイクがあると、RAMがInnoDBで見られる62.5%のしきい値を超えます。

MyISAM(サイドノート)

私の目を引くのは

Key buffer size / total MyISAM indexes: 2.0G/58.7M

MyISAMのインデックスがほとんどないため。key_buffer_sizeを64Mに設定できます。

そのためにmysqlを再起動する必要はありません。ただ走れ

SET GLOBAL ket_buffer_size = 1024 * 1024 * 64;

次に、これを変更します my.cnf

[mysqld]
key_Buffer_size = 64M

これにより、OSに2GBのRAMが割り当てられます。VMは単にあなたを愛してくれます!!!

試してみる !!!

警告

FLUSH TABLESInnoDBテーブルで実行すると、.ibdファイルに対してファイルが閉じられるだけです。これは実際には変更を直接プッシュしません。変更は、InnoDBのパイプを経由して移行する必要があります。これが、スパイクがに表示される理由ですModified db pages。InnoDBがフラッシュをスケジュールすると、変更された4262ページ(66.59 MB)がフラッシュされます。


詳細な分析をありがとうございました。今ではもっと理にかなっています-したがって、innodbバッファープールが時間の経過とともに最大メモリ使用量(20 GB)を維持するのは本当ですか?mysqldが使用するメモリの合計は82%ですか?
cherner 14年

それは両方の質問にはいだ
RolandoMySQLDBA

@RolandoMySQLDBA、私が正しく理解している場合、MySQLはメモリを解放せず、これがこれです。番号?
Malus Jan

1
@MalusJan私の答えは、解放されるメモリについてではありません。私の答えは、StorageEnginesとDB接続に使用されるRAMの量を扱います。ときどき、適切に閉じられていないDB接続が残っていると、割り当てられたRAMが滞る可能性があります。ストレージエンジンバッファーのキャッシュは、MyISAM(MySQL 5.x +)およびInnoDB(MySQL 5.7+)で動的にサイズ変更できます。DB接続のキャッシュは、(現在開いている接続ではなく)新しい着信接続用に動的にサイズ変更できます。メモリが解放されないのは、mysqldのメモリリークのバグが原因です。
RolandoMySQLDBA

@RolandoMySQLDBA。サーバーには10を超えるデータベースがあり、毎日ダンプを作成する必要があり、それぞれmysqldumpがメモリを消費し、それらを解放しません。したがって、すべてのダンプの後、ramプロセスの約80%がmysqlプロセスによって占有されています。そのための解決策はありますか?ありがとう
Malus Jan

0

私も同様の問題に直面しています。質問:分割メモリ構成を使用していますか?(THPと共有)はいの場合はhugepagesを無効にして、MySQLにメモリを処理させ、監視を続けます。また、スリープモードのプロセスを含め、サーバー上で実行されている並列プロセスの数を確認します。共有メモリ構成を使用している場合は、このサーバー用により多くのメモリが必要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.