データベース全体で UPDATE のパフォーマンスが時折大幅に低下することがありました。
たとえば、テーブル FooTable には varchar PK を持つ約 40 の列があり、さらに 10 のインデックスがあります。次のクエリは 44 秒かかりましたが、それ以外の場合はほぼ瞬時に実行されます。スローダウン中、サーバーの負荷平均は非常に低く (5 分間の平均で 1.5)、vmstat による IO もかなり妥当です。
ここに例があります:
mysql> update FooTable set BarColumn=1349981286086 where varcharPK='e4348411-0fbb-460a-80f7-f1de304a9f7c'
Query OK, 1 row affected (44.94 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> show profile for QUERY 1;
+----------------------+-----------+
| Status | Duration |
+----------------------+-----------+
| starting | 0.000030 |
| checking permissions | 0.000004 |
| Opening tables | 0.000007 |
| System lock | 0.000003 |
| Table lock | 0.000003 |
| init | 0.000035 |
| Updating | 44.949727 |
| end | 0.000006 |
| query end | 0.000003 |
| freeing items | 0.000115 |
| logging slow query | 0.000002 |
| logging slow query | 0.000052 |
| cleaning up | 0.000003 |
+----------------------+-----------+
13 rows in set (0.02 sec)
上記の例のクエリは、1 週間も前に「再構築」された (ALTER TABLE FooTable ENGINE=InnoDB;) InnoDB テーブルで実行された価値があります。私は当初、これが varchar/非シーケンシャル PK に関する InnoDB の既知のパフォーマンスの問題に関連しているのではないかと疑っていましたが、シーケンシャル PK を使用する他のテーブルがあり、同じ問題が見られました。
これは本番サーバー上にあります: Centos 5 2.6.18-238.19.1.el5 x86_64 MySQL/Percona 5.1.57-rel12.8-log 96GB のメモリと 58.8G のデータが 87 個のテーブルに分散されています。
関連する InnoDB 設定は次のとおりです。
innodb_flush_log_at_trx_commit = 2
innodb_buffer_pool_size = 70G
innodb_log_file_size = 512M
innodb_log_buffer_size = 64M
innodb_file_per_table = 1
innodb_thread_concurrency = 0
innodb_flush_method = O_DIRECT
innodb_read_io_threads = 64
innodb_write_io_threads = 64
optimizer_search_depth = 0
innodb_file_format = barracuda
このテーブルでは FORMAT=COMPRESSED を使用していませんが、他のテーブルでは使用しています。
非常に時間がかかっている更新フェーズで何が起こっているかを把握する方法について何か提案はありますか?