ユーザーが現在遅いと感じるサイト(Moodle)を実行しています。ディスクに一時テーブルを作成するMySQLに問題を追跡したと思います。 Mysql Workbenchサーバー管理で変数_created_tmp_disk_tables
_を監視していますが、その数は約50テーブル/秒で増加します。 1日の使用後、_created_tmp_disk_tables
_は> 100kです。また、メモリが解放されていないようです。システムがほとんど使用できなくなり、MySQLを再起動する必要があるまで、使用量は増加し続けます。ほぼ毎日再起動する必要があり、使用可能なメモリの約30〜35%を使用して、1日を80%で終了します。
データベースにblobがなく、クエリを制御することもできないため、クエリを最適化することはできません。 Percona Confirguration Wizard を使用して構成ファイルを生成しましたが、my.iniでも問題を解決できませんでした。
MySQLがディスクに一時テーブルを作成しないようにするには、何を変更すればよいですか?変更する必要がある設定はありますか?もっとメモリを投げる必要がありますか?
MySQLがメモリを使い果たすのを防ぐにはどうすればよいですか?
_slow_queries
_ログを有効にしたところ、クエリSELECT GET_LOCK()
のログが遅いことがわかりました。簡単な検索により、PHP=構成(_mysqli.allow_persistent = ON
_)で永続的な接続を許可していたことがわかりました。これをオフにしました。これにより、MySQLがメモリを消費する速度が低下しました。ただし、一時テーブル。
_key_buffer size
_が十分に大きいことも確認しました。変数_key_writes
_を調べました。これはゼロでなければなりません。そうでない場合は、_key_buffer_size
_を増やします。_key_reads
_と_key_writes
_がゼロであるため、_key_buffer_size
_は十分に大きいと想定しています。
Created_tmp_disk_tablesを増やすとテーブルがメモリに収まらない可能性があるため、_tmp_table_size
_および_max-heap-table-size
_を1024Mに増やしました。これはそれを解決しませんでした。
SHOW GLOBAL STATUS出力に毎秒多くの_sort_merge_passes
_が表示される場合は、_sort_buffer_size
_値を増やすことを検討できます。 1時間に2つの_sort_merge_passes
_があったので、_sort_buffer_size
_は十分な大きさであると考えています。
参照:_sort_buffer_size
_のMysqlマニュアル
@RolandoMySQLDBAの提案に従って、ソートおよび結合バッファーを変更しました。結果は下の表に表示されていますが、_created_tmp_tables_on_disk
_はまだ高いと思います。値を変更してmysqlサーバーを再起動し、1日(8時間)後に_created_tmp_tables_on_disk
_を確認して平均を計算しました。他に何か提案はありますか?なんらかのコンテナの中に収まらないものがあるように見えますが、それが何かはわかりません。
_+---------------------+-------------+-------------+--------------------+
| 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
_
my.ini
を見ると、2つの提案があります
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;
データはドライブD:
にあるため、ドライブC:
にディスクI/Oがある可能性があります。
このクエリを実行してください:
mysql> show variables like 'tmpdir';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tmpdir | C:\Windows\TEMP |
+---------------+-----------------+
1 row in set (0.00 sec)
デフォルトでmysqlをデスクトップで実行しているため、一時テーブルはドライブC:
に書き込まれています。ドライブDがドライブC:
より優れたディスクである場合、おそらくD:
に tmpdir を設定することにより、一時テーブルをドライブmy.ini
にマップできます。続く:
tmpdir="D:/DBs/"
tmpdir は動的変数ではないため、mysqlを再起動する必要があります。
MySQLがWindowsで実行されていて、コアパッケージのクエリに触れられないという事実を考えると、私は2つのアイデアを一緒に実行する必要があると考えています。
あなたはできるはずです
MoodleはそもそもLAMP用に設計されました。 localhostではなくLinuxマシンを指すように設定ファイルを変更するだけです。
MySQLの設定に関する古いMoodle 2.3ドキュメントへのリンクは次のとおりです: http://docs.moodle.org/23/en/Installing_Moodle#Create_an_empty_database
最新のドキュメントも入手できると思います。
次に、一時テーブルのターゲットフォルダとしてRAM diskを設定することをお勧めします
Jan 04, 2013
: 多くの一時テーブルをディスクに書き込まないようにするMySQLエンジンまたはトリックはありますか?Dec 17, 2012
: なぜMySQLは非常に多くの一時MYDファイルを生成するのですか? (実際の手順)Nov 30, 2012
: 多くのmysql一時テーブルを同時に作成するのは悪いですか?一時テーブルの作成は引き続き行われますが、ディスクではなくRAMに書き込まれます。ディスクI/Oを減らします。
高速RAID-0ディスク(32+ GB)でSUGGESTION#2を再検討し、ドライブT:(T for 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の高速化を唯一の代替手段として提供します。
私は完全性のためにここで自分の質問に答えます
@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
質問に示されています。
インメモリ一時テーブルサイズが最大ヒープテーブルサイズ変数によって制限されているかどうかも確認する必要があります。
メモリ内一時テーブル にMEMORYストレージエンジンを使用する場合、MySQLはメモリ内一時テーブルが大きくなりすぎるとディスク上のテーブルに自動的に変換します。
一時テーブルの作成に必要なスペースがtmp_table_size
またはmax_heap_table_size
、MySQLはサーバーのtmpdir
ディレクトリにディスクベースのテーブルを作成します。インメモリ一時テーブルの最大サイズは、tmp_table_size
またはmax_heap_table_size
値、どちらか小さい方。