MySQLはディスク上に一時テーブルを作成します。どうすれば止めることができますか?


27

ユーザーが現在遅いと感じるサイト(Moodle)を運営しています。私は、ディスク上に一時テーブルを作成するMySQLの問題を突き止めたと思います。created_tmp_disk_tablesMysql Workbenchサーバー管理で変数を見ると、その数は約50テーブル/秒で増加します。1日の使用後、created_tmp_disk_tables> 100kです。また、メモリは解放されていないようです。システムがほとんど使用できなくなり、MySQLを再起動するまで、使用量は増加し続けます。私はほぼ毎日それを再起動する必要があり、利用可能なメモリの約30〜35%を使用して開始し、80%で1日を終了します。

データベースにblobがなく、クエリを制御できないため、クエリを最適化することもできません。Percona Confirguration Wizardも使用しましたを使用して構成ファイルを生成しましたが、my.iniでも問題は解決しませんでした。

ご質問

  1. MySQLがディスク上に一時テーブルを作成しないようにするには、何を変更すればよいですか?変更する必要がある設定はありますか?もっとメモリを投入する必要がありますか?

  2. MySQLがメモリを使い果たすのを止めるにはどうすればよいですか?

編集

slow_queriesログを有効にすると、クエリのSELECT GET_LOCK()ログが遅いことがわかりました。クイック検索の結果、PHP構成で永続的な接続が許可されていたことがわかりました(mysqli.allow_persistent = ON)。これをオフにしました。これにより、MySQLがメモリを消費する割合が減少しましたが、一時テーブルはまだ作成されています。

また、key_buffer sizeが十分に大きいことも確認しました。変数を見ましたkey_writes。これはゼロでなければなりません。そうでない場合、key_buffer_size.I have zero key_readsand zeroを増やすkey_writesので、key_buffer_sizeが十分に大きいます。

私は増加tmp_table_sizeし、max-heap-table-sizeテーブルがメモリに収まることができないことを示すことがありcreated_tmp_disk_tablesの増加として1024Mに。これで解決しませんでした。

参照:http : //www.mysqlperformanceblog.com/2007/08/16/how-much-overhead-is-caused-by-on-disk-temporary-tables/

編集2

sort_merge_passesSHOW GLOBAL STATUS出力で1秒あたりの数が多い場合は、sort_buffer_size値を増やすことを検討できます。私はsort_merge_passes1時間で2つ持っていたので、sort_buffer_size十分に大きいと考えています。

参照:Mysqlマニュアル sort_buffer_size

編集3

@RolandoMySQLDBAの提案に従って、ソートバッファーと結合バッファーを変更しました。結果は下の表に表示されていますが、created_tmp_tables_on_diskまだ高いと思います。値を変更しcreated_tmp_tables_on_disk、1日(8時間)後にチェックして平均を計算した後、mysqlサーバーを再起動しました。他の提案はありますか?ある種のコンテナに収まらないものがあるように思えますが、それが何であるかを判断することはできません。

+---------------------+-------------+-------------+--------------------+
| Tmp_table_size,     | Sort_buffer | Join_buffer | No of created      |
| max_heap_table_size |             |             | tmp_tables on disk |
+---------------------+-------------+-------------+--------------------+
| 125M                | 256K        | 256K        |  100k/h            |
+---------------------+-------------+-------------+--------------------+
| 125M                | 512K        | 512K        |  100k/h            |
+---------------------+-------------+-------------+--------------------+
| 125M                | 1M          | 1M          |  100k/h            |
+---------------------+-------------+-------------+--------------------+
| 125M                | 4M          | 4M          |  100k/h            |
+---------------------+-------------+-------------+--------------------+   



これは私の構成です:

+-----------------------+-----------------------+
|DATABASE SERVER        |WEB SERVER             |
+-----------------------+-----------------------+
|Windows Server 2008 R2 |Windows Server 2008 R2 |
+-----------------------+-----------------------+
|MySQL 5.1.48           |IIS 7.5                |
+-----------------------+-----------------------+
|4 Core CPU             |4 Core CPU             |
+-----------------------+-----------------------+
|4GB RAM                |8GB RAM                |
+-----------------------+-----------------------+

追加情報

+--------------------+---------+
|PARAM               |VALUE    |
+--------------------+---------+
|Num of tables in Db |361      |
+--------------------+---------+
|Size of database    |2.5G     |
+--------------------+---------+
|Database engine     |InnoDB   |
+--------------------+---------+
|Read/write ratio    |3.5      |
|(Innodb_data_read/  |         |
|innodb_data_written)|         |
+--------------------+---------+
|Avg table size      |15k rows |
+--------------------+---------+
|Max table size      |744k rows|
+--------------------+---------+

このセットアップは私に与えられたので、私はそれを制御できません。WebサーバーはCPUとRAMをほとんど使用していないため、そのマシンをボトルネックとして除外しました。MySQL設定の大部分は、構成自動生成ツールからのものです。

代表的な数日間にわたってPerfMonを使用してシステムを監視しました。それから、ディスクにスワップしているのはOSではないと結論付けます。

My.ini

[client]
port=3306
[mysql]
default-character-set=utf8

[mysqld]
port=3306
basedir="C:/Program Files/MySQL/MySQL Server 5.1/"
datadir="D:/DBs/Data/"
default-character-set=utf8
default-storage-engine=INNODB
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
max_connections=125
query_cache_size=350M
table_cache=1520
tmp_table_size=125M
table-definition-cache= 1024
max-heap-table-size= 32M
thread_cache_size=38

MyISAM Specific options
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=125M
key_buffer_size=55M
read_buffer_size=1024K
read_rnd_buffer_size=256K
sort_buffer_size=1024K
join_buffer_size=1024K


INNODB Specific options
innodb_data_home_dir="D:/DBs/"
innodb_additional_mem_pool_size=32M
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=16M
innodb_buffer_pool_size=2G
innodb_log_file_size=407M
innodb_thread_concurrency=8

コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
ポールホワイトはGoFundMonicaを言う

回答:


16

を見てmy.ini、私は2つの提案があります

提案#1

あなたの次の設定を上げます my.ini

sort_buffer_size=4M
join_buffer_size=4M

これにより、いくつかの結合と並べ替えがメモリに残ります。もちろん、JOINまたはがORDER BY必要以上4Mになったら、ディスクにMyISAMテーブルとしてページングされます。

としてログインできない場合はroot@localhost、mysqlを再起動します

C:\> net stop mysql
C:\> net start mysql

root @ localhostとしてログインできる場合、これらの設定を使用するためにmysqlを再起動する必要はありません。

これをMySQLクライアントで実行するだけです。

SET @FourMegs = 1024 * 1024 * 4;
SET GLOBAL sort_buffer_size = @FourMegs;
SET GLOBAL join_buffer_size = @FourMegs;

提案#2

データはドライブにあるため、ドライブD:にディスクI / Oがある場合がありますC:

このクエリを実行してください:

mysql> show variables like 'tmpdir';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tmpdir        | C:\Windows\TEMP |
+---------------+-----------------+
1 row in set (0.00 sec)

デフォルトでmysqlをデスクトップで実行しているため、一時テーブルはDriveに書き込まれていますC:。DドライブがDriveよりも優れたディスクである場合C:、おそらく次のようにtmpdirD:設定することにより、一時テーブルをドライブにマップできます。my.ini

tmpdir="D:/DBs/"

tmpdirは動的変数ではないため、mysqlを再起動する必要があります。

試してみる !!!

更新2013-11-29 10:09 EST

提案#3

MySQLがWindowsで実行されており、コアパッケージのクエリに触れることができないという事実を考えると、一緒にやらなければならない2つのアイデアがあります。

アイデア#1:データベースをLinuxマシンに移動する

できるはずです

  • Linuxマシンをセットアップする
  • LinuxマシンにMySQLをインストールします
  • WindowsでMySQLのバイナリログを有効にする
  • データベースをテキストSQLファイルにmysqldump
  • Linuxで実行されているMySQLにSQLファイルをロードする
  • MySQL / WindowsからMySQL / Linuxへのレプリケーションのセットアップ

アイデア#2:Linuxマシンを指すようにMoodleを再構成する

MoodleはそもそもLAMP用に設計されました。localhostの代わりにLinuxマシンを指すように設定ファイルを変更するだけです。

MySQLの設定に関する古いMoodle 2.3ドキュメントへのリンクは次のとおりです:http : //docs.moodle.org/23/en/Installing_Moodle#Create_an_empty_database

最新のドキュメントも利用できると確信しています。

データベースをLinuxに移行するポイントは何ですか?

これは一時テーブルの状況にどのように役立ちますか????

次に、一時テーブルのターゲットフォルダとしてRAMディスクを設定することをお勧めします

一時テーブルの作成は引き続き行われますが、ディスクではなくRAMに書き込まれます。ディスクI / Oを削減します。

更新2013-11-29 11:24 EST

提案#4

高速RAID-0ディスク(32+ GB)でSUGGESTION#2を再検討し、ドライブT:(TはTemp)として構成することをお勧めします。そのようなディスクをインストールした後、これをmy.ini以下に追加します。

[mysqld]
tmpdir="T:\"

MySQLを再起動する必要があります。

net stop mysql
net start mysql

ところで、意図的にRAID-0を言ったので、RAID-1、RAID-10よりも優れた書き込みパフォーマンスを得ることができます。tmpテーブルディスクは、冗長にするものではありません。

@RaymondNijlandがコメントしているようにクエリを最適化しないと、一時テーブルの作成数を減らすことはできません。SUGGESTION #3そして、SUGGESTION #4オファーが唯一の代替として一時テーブルの作成と一時テーブルのI / Oを高速化。


13

完全を期すためにここで自分の質問に答えます

@RolandoMySQLDBAを優先回答として選択します。実際に問題を解決できなかったにもかかわらず、ほとんどのヒントが得られたからです。

以下は私の調査の結果です

結論

Windows上のMySQLは大量の一時テーブルを作成するだけで、構成ファイルの内容を変更してMySQLを調整しても役に立ちませんでした。

詳細

この表は、クエリを実行する前にmy.iniでそれぞれ変更したパラメーターの詳細を示しています。MySQLは各テストの間に再起動されました。

元の質問で見つかったmy.iniをテンプレートとして使用し、次の表に従ってパラメーターの値を1つずつ変更しました。

JMeterを使用して、10回繰り返される100の同時Web要求(使用状況を表す)を生成しました。Testしたがって、それぞれが合計1000件のリクエストで構成されていました。これにより、後続のデータベース呼び出しが発生しました。これは、MySQLが変更した構成パラメーターに関係なく、多くの一時テーブルを作成することを示していました。

+----+------------+-------+---------------+------------+
|Test|Parameter   |Value  |NumOfTempTables|Db Max Conn |
+----+------------+-------+---------------+------------+
| 1  |key_buffer_ | 25M   | 30682         | 29         |
|    |size        |       |               |            | 
+----+------------+-------+---------------+------------+
| 2  |key_buffer_ | 55M   | 30793         | 29         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 3  |key_buffer_ | 100M  | 30666         | 28         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 4  |key_buffer_ | 125M  | 30593         | 24         |
|    |size        |       |               |            | 
+----+------------+-------+---------------+------------+
| 5  |query_cache_| 100M  | 30627         | 32         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 6  |query_cache_| 250M  | 30761         | 26         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 7  |query_cache_| 500M  | 30864         | 83*        |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 8  |query_cache_| 1G    | 30706         | 75*        |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 9  |tmp_table_  | 125M  | 30724         | 31         |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 10 |tmp_table_  | 250M  | 30689         | 90*        |
|    |size        |       |               |            |
+----+------------+-------+---------------+------------+
| 11 |tmp_table_  | 500M  | 30792         | 28         |
|    |size        |       |               |            |  
+----+------------+-------+---------------+------------+
| 12 |Sort_buffer&| 256K  | 30754         | 28         |
|    |Join_buffer |       |               |            |
+----+------------+-------+---------------+------------+
| 13 |Sort_buffer&| 512K  | 30788         | 30         |
|    |Join_buffer |       |               |            | 
+----+------------+-------+---------------+------------+
| 14 |Sort_buffer&| 1M    | 30788         | 28         |
|    |Join_buffer |       |               |            | 
+----+------------+-------+---------------+------------+
| 15 |Sort_buffer&| 4M    | 30642         | 35         |
|    |Join_buffer |       |               |            |
+----+------------+-------+---------------+------------+
| 16 |innodb-     | 1G    | 30695         | 33         |
|    |buffer-     |       |               |            |
|    |pool-size   |       |               |            |
+----+------------+-------+---------------+------------+
| 17 |innodb-     | 2G    | 30791         | 28         |
|    |buffer-     |       |               |            |
|    |pool-size   |       |               |            | 
+----+------------+-------+---------------+------------+
| 18 |innodb-     | 3G    | 30719         | 34         |
|    |buffer-     |       |               |            |
|    |pool-size   |       |               |            |  
+----+------------+-------+---------------+------------+

* 3回の実行の平均

以下の図は、さまざまな構成に必要なメモリとCPUの量を示しています。黒い線は最小値と最大値を示し、青いバーは開始値と終了値を示します。最大メモリは4096M質問に示されたとおりでした。

メモリ使用量 CPU使用率


使用しているストレージエンジンは?MyiSAM?MyISAMテーブルを使用していない場合、key_buffer_sizeに依存しても意味がありません。innodbストレージエンジンを使用している場合、innodb_buffer_pool_sizeのサイズはどうなりますか。query_cacheを使用していますか?
KASI
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.