web-dev-qa-db-ja.com

MySQLがメモリ不足だと言うのはなぜですか?

かなり大きなINSERT...SELECT MySQLとJDBCで、次の例外が発生しました。

Exception in thread "main" Java.sql.SQLException: Out of memory (Needed 1073741824 bytes)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.Java:1073)

実際にはResultSetオブジェクトを返していないので、Javaヒープ領域は問題にならないはずです。しかし、とにかくそれを起動しようとしたところ、うまくいきませんでした。 MySQL Workbenchでステートメントを実行すると、基本的に同じものが得られます。

Error Code 5: Out of memory (Needed 1073741816 bytes)

これらの操作を完了するには、RAMを十分に用意する必要があります(選択するテーブル全体に収まるほど))が、さまざまな設定を利用して調整する必要があると思いますすべてのメモリ。AmazonEC2 ハイメモリダブルエクストララージインスタンス をWindows Server 2008 AMIで実行しています。my.iniファイルをいじって、より良い設定を使用しようとしましたが、すべての私は事態を悪化させたかもしれないことを知っています。ここにそのファイルのダンプがあります:

[client]
port=3306
[mysql]
default-character-set=latin1
[mysqld]
port=3306
basedir="C:/Program Files/MySQL/MySQL Server 5.5/"
datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
character-set-server=latin1
default-storage-engine=INNODB
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
max_connections=100
query_cache_size=1024M
table_cache=256
tmp_table_size=25G
thread_cache_size=8
myisam_max_sort_file_size=100G
myisam_repair_threads = 2
myisam_sort_buffer_size=10G
key_buffer_size=5000M
bulk_insert_buffer_size = 4000M
read_buffer_size=8000M
read_rnd_buffer_size=8000M
sort_buffer_size=1G
innodb_additional_mem_pool_size=26M
innodb_flush_log_at_trx_commit=2
innodb_log_buffer_size=13M
innodb_buffer_pool_size=23G
innodb_log_file_size=622M
innodb_thread_concurrency=18
innodb_file_per_table=TRUE
join_buffer_size=4G
max_heap_table_size = 10G

これは、上記の設定を変更して私の環境でより適切に機能するようにするだけの問題ですか?その場合、どの設定を使用すればよいですか?このインスタンスを使用するのは私だけです。大規模なデータセットの統計分析を含む個人的な趣味のプロジェクトに使用します。そのため、私は自分のクエリで利用可能なすべてのリソースを消費させることができます。

これがこれらの設定を変更する問題ではない場合、何が問題ですか?すべてをより適切に構成する方法について提供できる支援に感謝します。

9
Michael McGowan

これがWindowsインストールであるため、@ DTestは最初の適切な指示を提供しました。

次の式を適用します。

ほとんどの人はこれを使用します:

Maximum MySQL Memory Usage = innodb_buffer_pool_size + key_buffer_size + (read_buffer_size + sort_buffer_size) X max_connections

私はこれが好きです:

Maximum MySQL Memory Usage = innodb_buffer_pool_size + key_buffer_size + ((read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_size) X max_connections)

これらの変数は、インストールされたRAM以下の80%になるまで式を調整する必要があります。

sort_buffer_size
read_buffer_size
read_rnd_buffer_size
join_buffer_size
max_connections
9
RolandoMySQLDBA

バッファサイズを小さくしてみます。それらをあなたが持っているのと同じくらい大きくすると、問題が発生します。これらの値を実行するために使用できるメモリはどれくらいですか?

query_cache_size=1024M
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=10G
key_buffer_size=5000M
bulk_insert_buffer_size = 4000M
read_buffer_size=8000M
read_rnd_buffer_size=8000M
sort_buffer_size=1G
innodb_buffer_pool_size=23G

一部のバッファサイズはスレッドごとに割り当てられます。たとえば、myisam_sort_buffer_sizeが10Gの場合、各スレッドに10Gが割り当てられます。

私はまずこれらの値を劇的に減らし、次にこれだけに本当に必要な値を調査しますRAM(存在する場合))。

4
Derek Downey

MySQLが割り当てることができると考えるメモリの量を簡単に判断する方法は次のとおりです。

wget mysqltuner.pl

Perl mysqltuner.pl

このスクリプトを実行すると、インストールされているRAM MySQLが安全に割り当てることができると考えている割合がわかります。指定された答えが100%を超える場合は、必ずバッファーサイズを小さくする必要があります。主なものは次のとおりです。

sort_buffer_size
read_buffer_size
read_rnd_buffer_size
join_buffer_size
max_connections
key_buffer_size(4G以降は実際には効果的ではありません)

@DTestはすでに彼の回答であなたの方向性を設定しているため、彼のアンサーに+1します。 Perlスクリプトは、設定しなかった場合、または値を変更した場合にどうなるかを通知します。次に例を示します。

私のクライアントは
read_buffer_size = 128K
read_rnd_buffer_size = 256K
sort_buffer_size = 2M
join_buffer_size = 128K
max_connections = 1050

Mysqltuner.plからの出力は次のとおりです。

MySQLTuner 1.2.0-ヘイデン少佐
バグレポート、機能リクエスト、ダウンロード http://mysqltuner.com/
追加のオプションと出力フィルタリングのために「--help」で実行します
MySQL管理ログインを入力してください:lwdba
MySQL管理パスワードを入力してください:

--------一般統計---------------------------------------- ----------
[-] MySQLTunerスクリプトのバージョンチェックをスキップしました
[OK]現在実行中のサポートされているMySQLバージョン5.0.51a-community-log
[!!] 64ビットOSに切り替え-MySQLは現在、すべてのRAMを使用することはできません

--------ストレージエンジンの統計--------------------------------------- ----
[-]ステータス:+ Archive -BDB + Federated + InnoDB -ISAM -NDBCluster
[-] MyISAMテーブルのデータ:319M(テーブル:108)
[-] InnoDBテーブルのデータ:2M(テーブル:5)
[!!]断片化されたテーブルの総数:22

--------パフォーマンスメトリクス---------------------------------------- ---------
[-]有効期間:52日23時間15分57秒(72M q [15.875 qps]、241K接続、TX:2B、RX:1B)
[-]読み取り/書き込み:59%/ 41%
[-]合計バッファ:34.0Mグローバル+ 2.7M /スレッド(最大1050スレッド)
[!!] 2 GBを超える割り当てRAM 32ビットシステムでは、システムが不安定になる可能性があります
[!!]可能な最大メモリ使用量:2.8G(インストールされているRAMの72%)
[OK]クエリが遅い:0%(54/72M)
[OK]使用可能な接続の最大使用量:6%(65/1050)
[OK]キーバッファーサイズ/ MyISAMインデックスの合計:8.0M/82.1M
[OK]キーバッファヒット率:100.0%(4Bキャッシュ/ 1M読み取り)
[!!]クエリキャッシュが無効になっています
[OK]一時テーブルを必要とするソート:0%(0一時ソート/ 948Kソート)
[OK]ディスク上に作成された一時テーブル:3%(ディスク上に11K /合計380K)
[!!]スレッドキャッシュが無効になっています
[!!]テーブルキャッシュヒット率:0%(64オープン/ 32Kオープン)
[OK]使用されるオープンファイルの制限:2%(125/5K)
[OK]すぐに取得されたテーブルロック:99%(30M即時/ 30Mロック)
[OK] InnoDBデータサイズ/バッファプール:2.7M/8.0M

--------推奨事項----------------------------------------- ------------
一般的な推奨事項:
パフォーマンスを向上させるためにOPTIMIZE TABLEを実行してテーブルを最適化します
低速のクエリログを有効にして、不適切なクエリをトラブルシューティングします
thread_cache_sizeを開始値として4に設定します
ファイル記述子の制限を回避するためにtable_cacheを徐々に増やします
調整する変数:
query_cache_size(> = 8M)
thread_cache_size(4から開始)
table_cache(> 64)

パフォーマンス指標の下に注意してください

[-]合計バッファ:34.0Mグローバル+ 2.7M /スレッド(最大1050スレッド)

mySQLは/etc/my.cnfの設定に基づいて、インストール済みのRAM=の最大72%を割り当てることができます。

34Mはinnodb_buffer_pool_sizeとkey_buffer_sizeの組み合わせに基づいています

スレッドあたり2.7Mは、read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_sizeに基づいていました。

2.7Mの倍数は、max_connectionsに基づいています。

したがって、インストールされているRAMが100%未満(できれば80%未満)であることがパフォーマンスメトリックレポートで示されるまで、これらのパラメーターを調整する必要があります。

4
RolandoMySQLDBA

RAM=どれくらい持っているのですか?私はそれが少なくとも32GBだと思います。

innodb_buffer_pool_size-23G

それだけのRAMに適しています。

query_cache_size = 1G

大きすぎます。大きいと非効率です。 50M以下をお勧めします。

key-buffer_size = 5G

Windowsでは4G(まだ)のハードリミットがある可能性があり、4Gのハードリミットがありました。 5Gが1Gに変わった可能性があります。とにかく、すべてのテーブルがInnoDBである場合、なぜRAMを無駄にするのでしょう。 50Mに設定します。

エラーメッセージは正確に1Gだったので、sort_buffer_sizeのようなにおいがします。 32Mが妥当かもしれません。

1
Rick James