MySQLが非常に多くの一時MYDファイルを生成するのはなぜですか?


9

多くのPHP / MySQL Webサイト(フォトギャラリー)をホストしているDebian Linuxサーバーでは、のような「多数の」ファイルがある場合があります/tmp/#sql_6405_58.MYD

たとえば、今日:

[2012-12-15 15:18:11] /tmp/#sql_6405_6.MYD : 88MB
[2012-12-15 15:18:11] /tmp/#sql_6405_3.MYD : 22MB
[2012-12-15 15:18:11] /tmp/#sql_6405_4.MYD : 138MB
[2012-12-15 15:18:11] /tmp/#sql_6405_10.MYD : 88MB
...
[2012-12-15 15:18:11] /tmp/#sql_6405_9.MYD : 15MB
[2012-12-15 15:18:11] /tmp/#sql_6405_65.MYD : 49MB
[2012-12-15 15:18:11] /tmp/#sql_6405_44.MYD : 69MB

(同時に59ファイル、6GB以上の場合...はい/ tmpの大きなファイルを監視します)

残念ながら、/tmpと同じパーティション上に/あり、一時的にWebサーバーが壊れ/ます。その後、ファイルが消え、サーバーは通常の状態に戻ります。

すべてのファイル名は#sql_6405_*.MYDパターンに従います。どのMySQL操作が非常に多くの一時ファイルを意味するのかを理解したいと思います。このサーバーには約2000のデータベースがあります。どのデータベースが関係しているかを知ることは可能ですか?


1
私はそれらがを使用する大規模な操作の一時データfilesortであると思います。6405は、異なるサーバーインスタンスの一時ファイルを個別に保持するためのmysqlのPIDです。

管理者に質問を移動するように依頼する必要がありますか?

回答:


14

一時テーブルをMyISAMテーブルとしてマテリアライズしたり、遅延させるように構成したりできるオプションがいくつかあります。ディスクベースの一時テーブルの.frm場合、ファイルは存在せず.MYD.MYIファイルのみが存在することに注意してください(もちろん、内部一時テーブルにインデックスを付けることができないため、.MYIファイルは決して使用されません)。

オプションは次のとおりです。

また、内部一時テーブルの使用に関するMySQLドキュメントを検討する必要があります。

インメモリ一時テーブルが作成される状況は次のとおりです。

  • ORDER BY句と別のGROUP BY句がある場合、またはORDER BYまたはGROUP BYに結合キューの最初のテーブル以外のテーブルの列が含まれている場合、一時テーブルが作成されます。
  • DISTINCTとORDER BYを組み合わせると、一時テーブルが必要になる場合があります。
  • SQL_SMALL_RESULTオプションを使用する場合、クエリにディスク上のストレージを必要とする要素(後述)も含まれていない限り、MySQLはメモリ内の一時テーブルを使用します。

メモリ内の一時テーブルが(tmp_table_sizeまたはmax_heap_table_size)の最小値を超えると、mysqldは次のことを行います。

  • クエリを一時停止します
  • インメモリテーブルの内容をMyISAM一時テーブルにコピーします
  • インメモリテーブルを破棄します
  • クエリを続行し、一時データをMyISAM一時テーブルに送信します

インメモリ一時テーブルがディスクのためにバイパスされる状況は、

  • テーブル内のBLOBまたはTEXT列の存在
  • 512バイトを超えるGROUP BYまたはDISTINCT句の列の存在
  • UNIONまたはUNION ALLが使用されている場合、SELECTリストに512バイトを超える列が存在する

ディスク上の一時テーブルの作成を減らすには、ある程度の注意が必要です

  • join_buffer_sizeを大きく設定する
  • sort_buffer_sizeを大きく設定する
  • tmp_table_sizeとmax_heap_table_sizeを大きく設定する
  • 一時テーブルを最小化または防止するためのクエリのチューニング
  • インデックスを作成して、個々のテーブルから事前にソートされたデータのビューを作成する
  • 大きなメモリ内一時テーブルに対応するための追加のRAMのインストール

このような十分な注意を払った後も、ディスク上に一時テーブルがまだ形成されている場合は、1つの必死の動きがあります。ディスクベースの一時テーブルの作成をメモリにマッピングすることです。

tmpdirを使用して16GBのRAMディスクを設定する簡単な方法は次のとおりです

STEP01)RAMディスクフォルダーの作成

mkdir /var/mysql_tmpfs

STEP02)これを追加 my.cnf

[mysqld]
tmpdir=/var/mysql_tmpfs

STEP03)/ etc / fstabに追加します

echo "none /var/mysql_tmpfs tmpfs defaults,size=16g 1 2" >> /etc/fstab

STEP04)/ etc / fstabをリロードします

mount -a

STEP05) service mysql restart

この後、MyISAMになるすべての一時テーブルがRAMディスクに書き込まれます。これにより、ディスクベースの一時テーブルの作成が高速化されます。

試してみる !!!


1

結果はメモリに対して大きすぎるため、これらはディスクにロールオーバーするクエリです。

クエリが完了すると、スペースはクリアされます。

これらの一時ファイルをクエリと完全に一致させる方法はありませんが、SHOW FULL PROCESSLISTから適切な推測を行うための手がかりを得ることができます。またはSHOW INNODB STATUS; または、クエリが失敗した場合にエラーログを確認します。


1

テーブルでalterステートメントを使用するたびに、#sql_6405_3.MYDテンポレイファイルが作成され、完了すると出力がスローされて表示されなくなります。

テーブルを変更すると、MySQLはデータ全体を一時ファイル#sql.xxx.MYDにコピーし、作成された一時ファイルに変更を加えて、元のデータファイルtablename.MYDをドロップし、temporayファイルの名前をテーブル名に変更します。

また、いくつかの並べ替えクエリでは、一時ファイルが作成されます。

私がたどったように。このことが起こります。


0

大きな一時テーブルを作成するクエリは通常長時間実行されるため、問題のクエリは遅いクエリログで見つかるかもしれません。これは/tmp、同様の理由でパーティションがいっぱいであることがわかったサーバーで、今日私が助けた方法です大きなMySQL一時ファイル、それは4Gファイルであり、スロークエリログでクエリを見つけ、開発者に報告しました。彼らはクエリの破損を発見し、修正します。それは、制限されたMySQL命令のせいで実行されたため、実行されました長い間、4Gの一時ファイルを書き込んで/tmpパーティションを埋めました。

そして、この大きな一時ファイルの原因を見つける別の方法があります。それはバイナリなので、直接読み取ることはできませんが、このような文字列Linuxコマンドを使用して、含まれているテキストをgrepできることがわかりました。

strings name-of-mysql-temp-file

MySQLクエリの実行内容をテキストから確認して作成しました。

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