sql >> データベース >  >> RDS >> Mysql

MySQLのメモリ使用率が高いかどうかを確認する方法

    パフォーマンスの高いMySQLデータベースサーバーの重要な要素の1つは、特に実稼働環境で実行する場合に、メモリの割り当てと使用率が高いことです。しかし、MySQLの使用率が最適化されているかどうかをどのように判断できますか?メモリ使用率を高くすることは合理的ですか、それとも微調整が必​​要ですか?メモリリークが発生した場合はどうなりますか?

    これらのトピックを取り上げ、MySQLでチェックしてメモリ使用率の高い痕跡を特定できることを示しましょう。

    MySQLでのメモリ割り当て

    特定のサブジェクトタイトルを掘り下げる前に、MySQLがメモリをどのように使用するかについて簡単に説明します。同時トランザクションを処理し、大きなクエリを実行する場合、メモリは速度と効率のために重要なリソースを果たします。 MySQLの各スレッドは、クライアント接続の管理に使用されるメモリを必要とし、これらのスレッドは同じベースメモリを共有します。 thread_stack(スレッドのスタック)、net_buffer_length(接続バッファーと結果バッファーの場合)、または接続と結果が必要に応じてこの値まで動的に拡大するmax_allowed_pa​​cketのような変数は、メモリ使用率に影響を与える変数です。スレッドが不要になると、スレッドがスレッドキャッシュに戻らない限り、スレッドに割り当てられたメモリが解放されてシステムに戻されます。その場合、メモリは割り当てられたままになります。クエリ結合、クエリキャッシュ、並べ替え、テーブルキャッシュ、テーブル定義にはMySQLのメモリが必要ですが、これらは構成および設定できるシステム変数に起因します。

    ほとんどの場合、構成に設定されたメモリ固有の変数は、MyISAMやInnoDBなどのストレージベースの特定の構成を対象としています。 mysqldインスタンスがホストシステム内で生成されると、MySQLはバッファーとキャッシュを割り当てて、特定の構成で設定された設定値に基づいてデータベース操作のパフォーマンスを向上させます。たとえば、すべてのDBAがInnoDBに設定する最も一般的な変数は、変数innodb_buffer_pool_sizeとinnodb_buffer_pool_instancesであり、どちらもInnoDBテーブルのキャッシュデータを保持するバッファープールのメモリ割り当てに関連しています。大きなメモリがあり、バッファプールを複数のバッファプールインスタンスに分割して同時実行性を向上させるためにinnodb_buffer_pool_instancesを設定して、大きなトランザクションを処理することを期待している場合は望ましいです。

    MyISAMの場合、キーバッファが処理するメモリの量を処理するには、key_buffer_sizeを処理する必要があります。 MyISAMは、テーブル構造を含むすべての同時スレッドにバッファーを割り当て、各列に列構造を割り当て、サイズ3 * Nのバッファーを割り当てます(Nは最大行長であり、BLOB列は含まれません)。 MyISAMは、内部使用のために1つの追加の行バッファーも維持します。

    MySQLは、一時テーブルが大きくなりすぎない限り(tmp_table_sizeおよびmax_heap_table_sizeによって決定される)、一時テーブルにもメモリを割り当てます。 MEMORYテーブルを使用していて、変数max_heap_table_sizeが非常に高く設定されている場合、max_heap_table_sizeシステム変数がテーブルのサイズを決定し、オンディスク形式への変換がないため、これも大きなメモリを消費する可能性があります。

    MySQLには、MySQLアクティビティを低レベルで監視するための機能であるパフォーマンススキーマもあります。これを有効にすると、サーバーの起動時に必要なメモリを割り当てるのではなく、メモリを段階的に動的に割り当て、メモリ使用量を実際のサーバー負荷に合わせてスケーリングします。メモリが割り当てられると、サーバーが再起動されるまでメモリは解放されません。

    Linuxを使用している場合、およびカーネルがラージページのサポートに対して有効になっている場合、つまりHugePagesを使用している場合は、MySQLを構成してバッファプールに大容量のメモリを割り当てることもできます。

    MySQLメモリがハイになったときに確認する内容 実行中のクエリを確認する

    MySQL DBAが、実行中のMySQLサーバーで何が起こっているかを最初にベースにタッチすることは非常に一般的です。最も基本的な手順は、プロセスリストの確認、サーバーステータスの確認、およびストレージエンジンのステータスの確認です。これらのことを行うには、基本的に、MySQLにログインして一連のクエリを実行する必要があります。以下を参照してください:

    実行中のクエリを表示するには、

    mysql> SHOW [FULL] PROCESSLIST;

    現在のプロセスリストを表示すると、アクティブに実行されているクエリ、またはアイドル状態またはスリープ状態のプロセスでさえあるクエリが明らかになります。実行中のクエリの記録を保持することは非常に重要であり、重要なルーチンです。 MySQLがメモリを割り当てる方法について説明したように、クエリを実行するとメモリ割り当てが利用され、監視しないとパフォーマンスの問題が大幅に発生する可能性があります。

    MySQLサーバーのステータス変数を表示します

    mysql> SHOW SERVER STATUS\G
    または

    のような特定の変数をフィルタリングする
    mysql> SHOW SERVER STATUS WHERE variable_name IN ('<var1>', 'var2'...);

    MySQLのステータス変数は、統計データとして機能し、メトリックデータを取得して、ステータス値によって指定されたカウンターを監視することにより、MySQLのパフォーマンスを判断します。ここには、メモリ使用率に影響を与える一目でわかる特定の値があります。たとえば、スレッドの数、テーブルキャッシュの数、またはバッファプールの使用状況を確認します。

    ...
    
    | Created_tmp_disk_tables                 | 24240 |
    
    | Created_tmp_tables                      | 334999 |
    
    …
    
    | Innodb_buffer_pool_pages_data           | 754         |
    
    | Innodb_buffer_pool_bytes_data           | 12353536         |
    
    ...
    
    | Innodb_buffer_pool_pages_dirty          | 6         |
    
    | Innodb_buffer_pool_bytes_dirty          | 98304         |
    
    | Innodb_buffer_pool_pages_flushed        | 30383         |
    
    | Innodb_buffer_pool_pages_free           | 130289         |
    
    …
    
    | Open_table_definitions                  | 540 |
    
    | Open_tables                             | 1024 |
    
    | Opened_table_definitions                | 540 |
    
    | Opened_tables                           | 700887 |
    
    ...
    
    | Threads_connected                             | 5 |
    
    ...
    
    | Threads_cached    | 2 |
    
    | Threads_connected | 5     |
    
    | Threads_created   | 7 |
    
    | Threads_running   | 1 |

    InnoDBステータスなど、エンジンのモニターステータスを表示します

    mysql> SHOW ENGINE INNODB STATUS\G

    InnoDBステータスは、ストレージエンジンが処理しているトランザクションの現在のステータスも示します。トランザクションのヒープサイズ、そのバッファ使用量を明らかにするアダプティブハッシュインデックス、または以下の例のようにinnodbバッファプール情報を表示します。

    ---TRANSACTION 10798819, ACTIVE 0 sec inserting, thread declared inside InnoDB 1201
    
    mysql tables in use 1, locked 1
    
    1 lock struct(s), heap size 1136, 0 row lock(s), undo log entries 8801
    
    MySQL thread id 68481, OS thread handle 139953970235136, query id 681821 localhost root copy to tmp table
    
    ALTER TABLE NewAddressCode2_2 ENGINE=INNODB
    
    
    
    …
    
    -------------------------------------
    
    INSERT BUFFER AND ADAPTIVE HASH INDEX
    
    -------------------------------------
    
    Ibuf: size 528, free list len 43894, seg size 44423, 1773 merges
    
    merged operations:
    
     insert 63140, delete mark 0, delete 0
    
    discarded operations:
    
     insert 0, delete mark 0, delete 0
    
    Hash table size 553193, node heap has 1 buffer(s)
    
    Hash table size 553193, node heap has 637 buffer(s)
    
    Hash table size 553193, node heap has 772 buffer(s)
    
    Hash table size 553193, node heap has 1239 buffer(s)
    
    Hash table size 553193, node heap has 2 buffer(s)
    
    Hash table size 553193, node heap has 0 buffer(s)
    
    Hash table size 553193, node heap has 1 buffer(s)
    
    Hash table size 553193, node heap has 1 buffer(s)
    
    115320.41 hash searches/s, 10292.51 non-hash searches/s
    
    ...
    
    ----------------------
    
    BUFFER POOL AND MEMORY
    
    ----------------------
    
    Total large memory allocated 2235564032
    
    Dictionary memory allocated 3227698
    
    Internal hash tables (constant factor + variable factor)
    
        Adaptive hash index 78904768        (35404352 + 43500416)
    
        Page hash           277384 (buffer pool 0 only)
    
        Dictionary cache    12078786 (8851088 + 3227698)
    
        File system         1091824 (812272 + 279552)
    
        Lock system         5322504 (5313416 + 9088)
    
        Recovery system     0 (0 + 0)
    
    Buffer pool size   131056
    
    Buffer pool size, bytes 2147221504
    
    Free buffers       8303
    
    Database pages     120100
    
    Old database pages 44172
    
    Modified db pages  108784
    
    Pending reads      0
    
    Pending writes: LRU 2, flush list 342, single page 0
    
    Pages made young 533709, not young 181962
    
    3823.06 youngs/s, 1706.01 non-youngs/s
    
    Pages read 4104, created 236572, written 441223
    
    38.09 reads/s, 339.46 creates/s, 1805.87 writes/s
    
    Buffer pool hit rate 1000 / 1000, young-making rate 12 / 1000 not 5 / 1000
    
    Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
    
    LRU len: 120100, unzip_LRU len: 0
    
    I/O sum[754560]:cur[8096], unzip sum[0]:cur[0]
    
    …

    もう1つ追加することとして、MySQLサーバーによるメモリ消費と使用率を監視するためにパフォーマンススキーマとsysスキーマを使用することもできます。デフォルトでは、ほとんどのインストルメンテーションはデフォルトで無効になっているため、これを使用するには手動で行う必要があります。

    スワップネスを確認する

    どちらの方法でも、MySQLがメモリをディスクにスワップアウトしている可能性があります。これは、特にMySQLサーバーと基盤となるハードウェアが、予想される要件と並行して最適に設定されていない場合に、非常に一般的な状況になることがよくあります。トラフィックの需要が予測されていない場合があります。特に、不正なクエリが実行されて大量のメモリスペースが消費または使用され、データがバッファではなくディスクで選択されるため、パフォーマンスが低下する場合は、メモリがますます増大する可能性があります。 swappinessを確認するには、以下のようにfreememコマンドまたはvmstatを実行します。

    [[email protected] ~]# free -m
    
                  total        used free      shared buff/cache available
    
    Mem:           3790 2754         121 202 915         584
    
    Swap:          1535 39        1496
    
    [[email protected] ~]# vmstat 5 5
    
    procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
    
     r  b swpd   free buff  cache si so    bi bo in cs us sy id wa st
    
     2  0 40232 124100      0 937072 2 3 194  1029 477 313 7 2 91 1  0
    
     0  0 40232 123912      0 937228 0 0   0 49 1247 704 13 3 84  0 0
    
     1  0 40232 124184      0 937212 0 0   0 35 751 478 6 1 93  0 0
    
     0  0 40232 123688      0 937228 0 0   0 15 736 487 5 1 94  0 0
    
     0  0 40232 123912      0 937220 0 0   3 74 1065 729 8 2 89  0 0

    procfsを使用して確認し、/ proc/vmstatや/proc/meminfoに移動するなどの情報を収集することもできます。

    MassifでのPerf、gdb、Valgrindの使用

    perf、gdb、valgrindなどのツールを使用すると、MySQLのメモリ使用率を判断するためのより高度な方法を掘り下げるのに役立ちます。興味深い結果がメモリ消費を解決する謎になり、MySQLに戸惑うことがあります。これにより、より懐疑的な見方が必要になります。これらのツールを使用すると、MySQLがメモリの割り当てからトランザクションまたはプロセスの処理に使用するまで、メモリの処理をどのように使用しているかを調査できます。これは、たとえば、MySQLが異常な動作をしていて、構成が正しくないか、メモリリークが検出される可能性があることを確認している場合に役立ちます。

    たとえば、MySQLでperfを使用すると、システムレベルのレポートでより多くの情報が明らかになります。

    [[email protected] ~]# perf report --input perf.data --stdio
    
    # To display the perf.data header info, please use --header/--header-only options.
    
    #
    
    #
    
    # Total Lost Samples: 0
    
    #
    
    # Samples: 54K of event 'cpu-clock'
    
    # Event count (approx.): 13702000000
    
    #
    
    # Overhead  Command Shared Object        Symbol                                                                                                                                                                                             
    
    # ........  ....... ...................  ...................................................................................................................................................................................................
    
    #
    
        60.66%  mysqld [kernel.kallsyms]    [k] _raw_spin_unlock_irqrestore
    
         2.79%  mysqld   libc-2.17.so         [.] __memcpy_ssse3
    
         2.54%  mysqld   mysqld             [.] ha_key_cmp
    
         1.89%  mysqld   [vdso]             [.] __vdso_clock_gettime
    
         1.05%  mysqld   mysqld             [.] rec_get_offsets_func
    
         1.03%  mysqld   mysqld             [.] row_sel_field_store_in_mysql_format_func
    
         0.92%  mysqld   mysqld             [.] _mi_rec_pack
    
         0.91%  mysqld   [kernel.kallsyms]    [k] finish_task_switch
    
         0.90%  mysqld   mysqld             [.] row_search_mvcc
    
         0.86%  mysqld   mysqld             [.] decimal2bin
    
         0.83%  mysqld   mysqld             [.] _mi_rec_check
    
    ….

    これは掘り下げる特別なトピックになる可能性があるため、参照としてこれらの非常に優れた外部ブログを調べること、MySQLプロファイリングのperf Basics、perfを使用したMySQLスケーリングの問題の発見、または方法を学ぶことをお勧めしますmassifでvalgrindを使用してデバッグします。

    MySQLのメモリ使用率をチェックする効率的な方法

    ClusterControlを使用すると、Runbookを調べたり、レポートを配信する独自​​のプレイブックを作成したりするなどの面倒なルーチンが軽減されます。 ClusterControlには、MySQLノードの概要をすばやく確認できるダッシュボード(SCUMMを使用)があります。たとえば、MySQLGeneralダッシュボードを表示する

    MySQLノードのパフォーマンスを判断できます

    上の画像は、MySQLのメモリ使用率に影響を与える変数を示しています。ソートキャッシュ、一時テーブル、接続されたスレッド、クエリキャッシュ、またはストレージエンジンのinnodbバッファプールまたはMyISAMのキーバッファのメトリックを確認できます。

    ClusterControlを使用すると、実行中のクエリをチェックして、高いメモリ使用率に影響を与える可能性のあるプロセス(クエリ)を特定できるワンストップユーティリティツールが提供されます。例については、以下を参照してください

    MySQLのステータス変数の表示は非常に簡単です

    [パフォーマンス]->[Innodbステータス]に移動して、データベースノードの現在のInnoDBステータス。また、ClusterControlでは、インシデントが検出され、インシデントの収集を試み、MySQLFreezeFrameに関する以前のブログで示したようにInnoDBステータスを提供するレポートとして履歴を表示します。

    概要

    使用する手順とツールを知っている限り、メモリ使用率が高いと思われる場合のMySQLデータベースのトラブルシューティングと診断はそれほど難しくありません。適切なツールを使用すると、柔軟性と生産性が向上し、修正やソリューションを提供して、より大きな成果を上げることができます。


    1. PL/pgSQL関数から不明な列を持つ動的テーブルを返します

    2. カンマ区切りの値を区切り、SQLサーバーのテーブルに保存します

    3. Oracle11gでのXMLtable

    4. SQL ServerでNULLを別の値に置き換える方法– ISNULL()