お客様のデータベースを追加のサーバーに移動した後、問題が発生しました。これはサイトのパフォーマンスにプラスの影響を与えるはずでしたが、MyISAMのテーブルロックに問題があります。 (MyISAMの代わりにInnoDBを使用することを聞いたことがありますが、近い将来エンジンを変更することはできません)。
モデレーターが記事サイトのコメントをアクティブ化するときに実行される更新クエリにそれを見つけることができます。これはプロセスです:
SET status = 1 WHERE id = 5
(インデックスが設定されている)この時点で、ページ全体が遅くなります。データベース自体は数分間ビジーです。私はプロセスリストを数回フェッチし、さまざまな選択クエリの約60のエントリを確認しました。これらはすべて状態テーブルレベルのロックを待機中でした。
1。なぜこの更新がテーブルで行われるのか理解できませんarticle_comments
は、テーブルarticle
がテーブルレベルのロックを待機するためのselect-statementsに影響を与える可能性があります。プロセスリストでは、待機中のほとんどすべてのクエリがこのテーブルからのものでした。 selectよりもupdate/insertが優先され、これによりこのような問題が発生する可能性があるという事実を読みましたが、記事テーブル自体はコメントがアクティブになっても更新されないので、selectは待つべきではありません。私はそれを誤解しましたか?
2。この動作を防ぐため、または少なくともより良いバランスを得るために、InnoDBに変更する以外に何かありますか?データベースを新しいサーバーに移動する前にこの問題が発生しなかったという事実に非常に苛立ちました。いくつかの設定ミスがあると思いますが、特定する方法がわかりません。
MyISAMストレージエンジンは、DML(INSERT、UPDATE、DELETE)に対してフルテーブルロックを実行することで猛烈に悪名高くなっています。 InnoDBは間違いなく長期的にその問題を解決します。
MyISAMとInnoDBを使用する場合の長所と短所について書いた
現在の質問に関して、考えられるシナリオは次のとおりです。
article
とarticle_comments
はどちらもMyISAMテーブルですarticle_comments
には、status
を列とする1つ以上のインデックスがありますarticle_comments
のインデックスページの更新がMyISAMキーバッファーにキャッシュされます(サイズは key_buffer_size )。これにより、古いインデックスが作成されますMyISAMキーバッファーからのページarticle
とarticle_comments
の間でJOINを実行するSELECTクエリがあります私の提案するシナリオでは、article_comments
がDML(この場合はarticle
)から解放されるのを待つ必要があるため、UPDATE
テーブルに対するSELECTは書き込みを許可しないようにすることができます
この時点で、ページ全体が遅くなります。データベース自体は数分間ビジーです。
大きなQuery_cacheがあるようなにおいですか?
mysql> SHOW VARIABLES LIKE 'query_cache%';
+------------------------------+----------+
| Variable_name | Value |
+------------------------------+----------+
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 16777216 | -- Not over 50M
| query_cache_type | DEMAND | -- Only if using SQL_CACHE
| query_cache_wlock_invalidate | OFF |
+------------------------------+----------+
書き込みが多い本番システムでは、query_cacheをオフにすることもできます。
All指定されたテーブルのquery_cacheのエントリは、そのテーブルにanyの書き込みが発生すると削除されます。 QCが大きいほど、このタスクは遅くなります。
MyISAMは「テーブルレベル」のロックを使用します。読み取りと書き込みを同時に(同じテーブルで)行うことはできません。粗野ですが効果的です。