web-dev-qa-db-ja.com

大きなファイルを挿入すると、MySQLで「メモリ不足」エラーが発生する。このファイルサイズの制限はどこから発生していますか?

MySQLデータベースを使用してファイルを保存しています。

私が使用しているテーブルは、次のように構成されています。

+--------------+----------+------+-----+---------+-------+
| Field        | Type     | Null | Key | Default | Extra |
+--------------+----------+------+-----+---------+-------+
| AttachmentID | int(11)  | NO   | PRI | NULL    |       |
| Data         | longblob | NO   |     | NULL    |       |
+--------------+----------+------+-----+---------+-------+

私が使用しているINSERTコマンドは、可能な限りシンプルです。

INSERT INTO table (AttachmentID, Data) VALUES (attachmentID, attachmentData);

明らかに、attachmentIDはintであり、attachmentDataは大きなバイト配列です。

データベースにファイルを保存する方法に関するいくつかのガイドを読んだ後、max_allowed_packet設定ファイルの設定を「512M」に設定すると、実際に挿入するファイルには十分すぎるほどです。

これは、30MBから40MBのいくつかのファイルで問題なく動作しました。ただし、90MB以上の範囲の大きなファイルを挿入するようになったため、挿入しようとしたファイルのサイズと同じバイト数が必要な「メモリ不足」例外が発生します。

サーバーは仮想サーバーであり、4GBが割り当てられており、干渉している可能性のある他のものが実行されていません。

小さいファイルではなく、大きいファイルに対してメモリ不足エラーが発生するのはなぜですか? このファイルサイズの制限はどこで発生していますか?

以下に設定ファイルを含めました:

[client]
port        = 3306
socket      = /tmp/mysql.sock

[mysqld]
port        = 3306
socket      = /tmp/mysql.sock
skip-locking
key_buffer_size = 256M
table_open_cache = 256
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size= 16M
thread_concurrency = 8
max_allowed_packet = 512M

ft_min_Word_len=2

ignore-builtin-innodb
plugin-load=innodb=ha_innodb_plugin.so

log-bin=mysql-bin
binlog_format=mixed
server-id = 1

[mysqldump]
quick
max_allowed_packet = 16M

[mysql]
no-auto-rehash

[myisamchk]
key_buffer_size = 128M
sort_buffer_size = 128M
read_buffer = 2M
write_buffer = 2M

[mysqlhotcopy]
interactive-timeout

編集:私は41,586 KBのサイズのファイルを正常にINSERTできますが、44,119 KBのファイルはできません。限界はそれらの間のどこかにあります。

6
Ben Jenkinson

私はあなたが持つかもしれない最大のブロブについての質問への興味深い答えを見ました

これがServerFaultで見たステートメントです

innodb_log_file_sizeとinnodb_log_buffer_sizeの合計は、大きなものがある場合、最大のblobオブジェクトの10倍より大きくなければなりません

My.cnfにInnoDB設定がありませんでした

InnoDBビルトインを無効にし、別のInnoDBを接続したようです

Innodb_log_file_sizeおよびinnodb_log_buffer_sizeを調整して調整できるかどうかを確認してください。

4 GBしかRAM=予約されていないので、InnoDBログファイルをはるかに大きくしてみてください

/etc/my.cnfでinnodb_log_file_sizeを1Gに変更します

  1. サービスmysql停止
  2. 睡眠30
  3. rm -f/var/lib/mysql/in_logfile [01]
  4. mysql startサービス(ib_logfile0およびib_logfile1を再作成)

試してみる !!!

3
RolandoMySQLDBA

これ自体は答えではありませんが、このトピックに対する非常に良いアドバイスです。

大きなファイルをデータベースに保存しないでください。

とにかくそれらはDBに保存されることになっているのですか?ファイルシステムを介してそれにアクセスする方がより効率的に処理でき、テーブルからの大規模な膨張を回避できます。これらのファイルが頻繁に変更される場合(これがシナリオに当てはまるかどうかがわからない場合)、DBサーバーに大きな負荷がかかります。クライアント(または他の場所)にファイルを送信するためのWebサーバー+ファイルシステムがあるため、ファイルの読み取りも非常に高速です。

参照としてデータベースにファイルのパスを保存するだけの方が(IMO)の方が適切です。ファイルを保護するためにこれを行う場合は、.htaccessを使用するか、Webサーバー自体を介したファイルへの直接フ​​ァイルアクセスをブロックし、これらのファイルのラッパーを使用する必要があります(PHPでは... file.php?file = myfileのようなもの) ACLやその他のceckを実行できるように.pdf。NETを使用していることを読んで、このようなものが利用可能であることも確信しています)、またはサーバー/言語が提供する他のメカニズムを使用してください。

2
DrColossos

フロントエンドのアプリケーション/プログラミング言語も確認する必要があります。たとえば、PHPを使用している場合は、php.iniファイル(または)でupload_max_filesize and post_max_sizeを確認します。これらを目的の値に設定します:upload_max_filesize = 100M post_max_size = 100M

1
StanleyJohns