web-dev-qa-db-ja.com

危険なほど高いMySQLの最大メモリ使用量の支援

誰でも私がこのMySQL設定をチェックするのを手伝ってくれる? VPS 32GB RAM-8 vcpuで1つのeコマースを実行しています。

MySQLTunerは私を返します:

Variables to adjust:
  *** MySQL's maximum memory usage is dangerously high ***
  *** Add RAM before increasing MySQL buffer variables ***
    join_buffer_size (> 140.0M, or always use indexes with JOINs)
    tmp_table_size (> 32M)
    max_heap_table_size (> 32M)
    table_open_cache (> 407)

my.cnf設定は次のとおりです。

key_buffer_size = 256M
join_buffer_size = 140M
tmp_table_size   = 80M
max_heap_table_size = 80M
thread_pool_size = 24
innodb_buffer_pool_instances = 6
innodb_buffer_pool_size = 6G
innodb_log_file_size = 768M
table_open_cache = 4000
skip_name_resolve = 1

max_allowed_packet      = 16M
thread_stack            = 192K
thread_cache_size       = 8
max_connections         = 200
#table_cache            = 1024
#thread_concurrency     = 40

tmp-table-size          = 32M
max-heap-table-size     = 32M

query_cache_limit       = 4M
query_cache_size        = 0
query_cache_type        = 0

追加情報

-------- Storage Engine Statistics -----------------------------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MEMORY +MRG_MYISAM +MyISAM +PERFORMANCE_SCHEMA
[--] Data in InnoDB tables: 76.4M (Tables: 102)
[--] Data in MyISAM tables: 1.3G (Tables: 229)
[OK] Total fragmented tables: 0

-------- Performance Metrics -----------------------------------------------------------------------
[--] Up for: 1d 19h 15m 53s (19M q [124.090 qps], 69K conn, TX: 21G, RX: 6G)
[--] Reads / Writes: 98% / 2%
[--] Binary logging is disabled
[--] Physical Memory     : 31.5G
[--] Max MySQL memory    : 33.8G
[--] Other process memory: 650.8M
[--] Total buffers: 6.3G global + 140.8M per thread (200 max threads)
[--] P_S Max memory usage: 72B
[--] Galera GCache Max memory usage: 0B
[OK] Maximum reached memory usage: 9.5G (30.04% of installed RAM)
[!!] Maximum possible memory usage: 33.8G (107.34% of installed RAM)
[!!] Overall possible memory usage with other process exceeded memory
[OK] Slow queries: 0% (114/19M)
[OK] Highest usage of available connections: 11% (23/200)
[OK] Aborted connections: 0.01%  (5/69987)
[OK] Query cache is disabled by default due to mutex contention on multiprocessor machines.
[OK] Sorts requiring temporary tables: 0% (3K temp sorts / 5M sorts)
[!!] Joins performed without indexes: 604
[!!] Temporary tables created on disk: 31% (796K on disk / 2M total)
[OK] Thread cache hit rate: 99% (29 created / 69K connections)
[!!] Table cache hit rate: 0% (400 open / 5M opened)
[OK] Open file limit used: 42% (440/1K)
[OK] Table locks acquired immediately: 99% (33M immediate / 33M locks)



-------- MyISAM Metrics ----------------------------------------------------------------------------
[!!] Key buffer used: 19.4% (52M used / 268M cache)
[OK] Key buffer size / total MyISAM indexes: 256.0M/66.2M
[OK] Read Key buffer hit rate: 98.8% (991M cached / 12M reads)
[!!] Write Key buffer hit rate: 51.6% (511K cached / 263K writes)

-------- InnoDB Metrics ----------------------------------------------------------------------------
[--] InnoDB is enabled.
[--] InnoDB Thread Concurrency: 0
[OK] InnoDB File per table is activated
[OK] InnoDB buffer pool / data size: 6.0G/76.4M
[OK] Ratio InnoDB log file size / InnoDB Buffer pool size: 768.0M * 2/6.0G should be equal 25%
[OK] InnoDB buffer pool instances: 6
[--] Number of InnoDB Buffer Pool Chunk : 48 for 6 Buffer Pool Instance(s)
[OK] Innodb_buffer_pool_size aligned with Innodb_buffer_pool_chunk_size & Innodb_buffer_pool_instances
[OK] InnoDB Read buffer efficiency: 100.00% (518324644 hits/ 518327944 total)
[!!] InnoDB Write Log efficiency: 38.31% (36637 hits/ 95624 total)
[OK] InnoDB log waits: 0.00% (0 waits / 58987 writes)

完全なMySQLTunerレポート:

https://Pastebin.com/53r7cuXv

SHOW GLOBAL STATUS;

https://Pastebin.com/ZKptibfK

SHOW GLOBAL VARIABLES;

https://Pastebin.com/FBazhWT2

htop

htop here

root@xxxxxxxxxxx ~ # ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 128903
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65536
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 128903
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

enter image description here

すべてのMySQLテーブルをInnoDBに変更する必要がありますか?

3
Augusto Murri

1秒あたりのレート= my.cnf [mysqld]セクションで検討するRPSの提案

join_buffer_size=256K  # from 140M for row pointers
thread_cache_size=40  # from 8 to avoid thread starvation
query_cache_limit=0  # from 4M since you have QC turned OFF
innodb_lru_scan_depth=100  # from 1024 to reduce CPU busy every SECOND
key_cache_age_threshold=7200  # from 300 seconds to reduce key_reads RPS
key_cache_division_limit=50  # from 100 percent for HOT/WARM caches
key_cache_block_size=16K  # from 1K to evict bigger block when full
open_files_limit=30000  # from 1024 to reduce opened_files RPS
table_open_cache=10000  # from 407 to reduce opened_tables RPS
table_definition_cache=2000  # from 603 to reduce opened_table_definitions RPS
1
Wilson Hauck

所見:

  • バージョン:5.7.22-22-log
  • 32 GBのRAM
  • 稼働時間= 2d 20:05:30
  • Windowsではありません
  • 64ビットバージョンの実行
  • 完全に(またはほとんど)MyISAMを実行しているようです。

より重要な問題:

(多くの理由で)MyISAMからInnoDBに移行します。 MyISAMからInnoDBへの変換

データ量が少ないため、key_buffer_sizeまたはinnodb_buffer_pool_sizeを増やす必要はありません。データセットのサイズを大幅に増やす場合は、これに対処する必要があります。

OSでulimit -nを増やします。プロセスごとに1024のデフォルト制限があるようです。これにより、いくつかのキャッシュを大きくすることができます。 table_open_cacheは407に自動サイズ調整されたと思いますが(これは低すぎるようです)。 OS制限を増やすことで、キャッシュのサイズが自動で大きくなる可能性があります。

一部のクエリは、実際よりも効率が悪いようです。あなたがそのようなものを識別することができたら、それらを議論しましょう。これには、より良いインデックス、複合インデックス、TEXTの回避、SELECT *の回避などが含まれる場合があります。

詳細およびその他の観察:

( Opened_tables ) = 8,715,435 / 245130 = 36 /sec-テーブルを開く頻度-table_open_cacheを増やす

( open_files_limit ) = 1,024-ulimit -n-より多くのファイルを許可するには、ulimitまたは/etc/security/limits.confまたはsysctl.conf(kern.maxfiles&kern.maxfilesperproc)またはその他(OSに依存)を変更します

( Table_open_cache_overflows ) = 8,713,321 / 245130 = 36 /sec-table_open_cacheを増やす必要があるかもしれません

( Table_open_cache_misses ) = 8,715,416 / 245130 = 36 /sec-table_open_cacheを増やす必要があるかもしれません

( expand_fast_index_creation ) = expand_fast_index_creation = OFF-ONを使用すると、ALTERおよびOPTIMIZEが大幅に高速化されます。 -おそらくONにする方が良いでしょう。

( query_prealloc_size / _ram ) = 8,192 / 32768M = 0.00%-解析用。 RAM-16Kの割合

( query_alloc_block_size / _ram ) = 8,192 / 32768M = 0.00%-解析用。 RAM-16Kの割合

( local_infile ) = local_infile = ON-local_infile = ONは潜在的なセキュリティ問題です

( Key_blocks_used * 1024 / key_buffer_size ) = 14,984 * 1024 / 256M = 5.7%-使用されたkey_bufferの割合。最高水位標。 -不要なメモリ使用を回避するためにkey_buffer_sizeを小さくします。

( Key_writes / Key_write_requests ) = 445,704 / 787046 = 56.6%-書き込みに対するkey_bufferの効果-十分なRAMがある場合、key_buffer_sizeを増やすことは価値があります。

( Key_reads ) = 19,835,995 / 245130 = 81 /sec-MyISAMインデックスの(ディスクからの)読み取り速度-十分なRAMがある場合、key_buffer_sizeを増やすことは価値があります。

( Key_reads + Key_writes ) = (19835995 + 445704) / 245130 = 83 /sec-MyISAMインデックスI/Oレート-十分なRAMがある場合、key_buffer_sizeを増やすことは価値があります。

( Created_tmp_disk_tables ) = 1,260,364 / 245130 = 5.1 /sec-複雑なSELECTの一部としてdisk "temp"テーブルを作成する頻度-tmp_table_sizeとmax_heap_table_sizeを増やします。 MyISAMの代わりにMEMORYを使用する場合の一時テーブルのルールを確認してください。おそらく、マイナーなスキーマまたはクエリの変更により、MyISAMを回避できます。インデックスの改善とクエリの再構成が役立つ可能性が高くなります。

( Created_tmp_disk_tables / Questions ) = 1,260,364 / 31058077 = 4.1%-ディスク上のtmpテーブルを必要とするクエリの割合。 -インデックスの向上/ Blobなし/など.

( Com_delete / Com_insert ) = 62,986 / 50111 = 125.7%-削除/挿入(PCTとして)。 (LOAD、REPLACEなどを無視します。)

( Select_scan ) = 1,928,326 / 245130 = 7.9 /sec-テーブル全体のスキャン-インデックスを追加する/クエリを最適化する(小さなテーブルでない限り)

( Select_scan / Com_select ) = 1,928,326 / 30171997 = 6.4%-全テーブルスキャンを実行する選択の%。 (ストアドルーチンにだまされる可能性があります。)-インデックスを追加する/クエリを最適化する

( back_log / max_connections ) = 90 / 200 = 45.0%

異常に大きい:

Com_show_profile = 0.044 /HR
Select_full_range_join = 61,564
Select_range / Com_select = 23.8%
join_buffer_size = 140MB
Flush_commands = 0.19 /HR
1
Rick James

1秒あたりのレート= RPS my.cnf [mysqld]セクションで考慮すべき追加の提案

max_heap_table_size=48M  # from 32M  for additional capacity
tmp_table_size=48M  # from 32M to reduce created_tmp_disk_tables count
innodb_io_capacity=1600  # from 200 to allow more IOPS
read_rnd_buffer_size=192K  # from 256K to reduce handler_read_rnd_next RPS
sort_buffer_size=2M  # from 256K to reduce sort_merge_passes count
1
Wilson Hauck

他の人(MyISAMテーブルを使用しているため、このOPではありません)の場合、MySQL 5.7では、主にINNODBテーブルを使用していると想定して、次のクエリを実行することで現在使用されているメモリ量を確認できます。

SHOW ENGINE INNODB STATUS

次のクエリを実行することで、インスタンスがバッファリングのみに必要なメモリの最大量を確認できます。

SELECT ( @@key_buffer_size
+ @@query_cache_size
+ @@innodb_buffer_pool_size
+ @@innodb_log_buffer_size
+ @@max_allowed_packet
+ @@max_connections * ( 
    @@read_buffer_size
    + @@read_rnd_buffer_size
    + @@sort_buffer_size
    + @@join_buffer_size
    + @@binlog_cache_size
    + @@net_buffer_length
    + @@net_buffer_length
    + @@thread_stack
    + @@tmp_table_size )
) / (1024 * 1024 * 1024) AS MAX_MEMORY_GB;
  • 「接続バッファー」と「結果バッファー」のnet_buffer_lengthが2回

その最大メモリ量は、サーバーで利用可能な量を超えていますか?特にAWS Auroraでは、これによりDBが定期的に再起動します。

1

Join_buffer_size、tmp_table_size、max_heap_table_sizeをあまり高く設定しないでください。 max_connectionsが200に達したと想定すると、最悪の場合のクエリでは、接続ごとに(join_buffer_size + max(tmp_table_size、max_heap_size)+その他の割り当て)を使用できます。これはメモリ制限にかなり近いです。

これらのバッファーの値が大きいと、必ずしも役立つとは限りません。

「ストレージエンジン統計」に基づいて、VPSが大きすぎるようです。

1
danblack

ストレージエンジンの統計に基づいています。ほとんどのデータはMyISAMベースのテーブルに依存しています。これは問題のある部分として表示されます。行レベルのロックとパフォーマンスの向上を活用するには、InnoDBに切り替える必要があります。読み取りワークロードの大部分がある場合は、MyISAMのみを使用する必要があります。それ以外の場合は、次の手順を使用してInnoDBに切り替えます。

ステップ1:変更を適用する前にデータベースをバックアップします。

ステップ2:MyISAMのすべてのテーブルの変更クエリを生成

SELECT CONCAT('ALTER TABLE ', TABLE_SCHEMA, '.', TABLE_NAME, ' engine=InnoDB;') 
FROM information_schema.TABLES WHERE ENGINE = 'MyISAM'
AND TABLE_SCHEMA NOT IN ('mysql', 'sys');

ステップ3:ステップ2の出力として受け取ったすべての変更クエリを実行します

MyISAMを続行する場合。以下を微調整する必要があります

key_buffer_size = 256M innodb_buffer_pool_size = 6G

key_buffer_size = 512M innodb_buffer_pool_size = 3G

0