web-dev-qa-db-ja.com

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

多くの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のデータベースがあります。どのデータベースが関係しているかを知ることは可能ですか?

9
plegall

一時テーブルを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つの必死の動きがあります。ディスクベースの一時テーブルの作成をメモリにマッピングすることです。

16GB RAM Disk using tmpdir

STEP01)RAM Disk Folderを作成します

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ディスクに書き込まれます。これにより、ディスクベースの一時テーブルの作成が高速化されます。

試してみる !!!

14
RolandoMySQLDBA

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

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

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

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

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

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

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

1
Vinay

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

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

strings name-of-mysql-temp-file

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

0
linuxman1