MySQL MyISAMディスクバインドスケーリングの問題/ドライブキャッシュ
質問
次のルックアップテーブルがあります:
CREATE TABLE `widgetuser` (
`widgetuserid` char(40) NOT NULL,
`userid` int(10) unsigned NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`widgetuserid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 DELAY_KEY_WRITE=1;
同じ構造のwidgetuser_tmpテーブルがありますが、キーはなく、widgetuserテーブルにこのデータ(4mio行)を入力します:
mysql> insert into widgetuser select * from widgetuser_tmp limit 0,4000000;flush tables;
Query OK, 4000000 rows affected (33.14 sec)
Records: 4000000 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (0.91 sec)
書き込み中は、15MB / sのRAID-1に直接移動し、ディスク使用率は<!> lt; 50%であり、ディスクキャッシュをソーステーブルで満たしたため、読み取りはありません。
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
sda 0.00 3839.20 0.00 52.40 0.00 15.20 594.20 12.46 237.75 5.57 29.20
sdb 0.00 3839.00 0.00 52.60 0.00 15.20 591.94 14.50 275.59 7.19 37.80
次の1 Mio行を挿入します。すべて問題なく、wMB / sはフラッシュ直後に0に戻ります。
mysql> insert into widgetuser select * from widgetuser_tmp limit 4000000,1000000;flush tables;
Query OK, 1000000 rows affected (10.18 sec)
Records: 1000000 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (0.87 sec)
mysql> insert into widgetuser select * from widgetuser_tmp limit 5000000,1000000;flush tables;
Query OK, 1000000 rows affected (10.21 sec)
Records: 1000000 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (1.02 sec)
mysql> insert into widgetuser select * from widgetuser_tmp limit 6000000,1000000;flush tables;
Query OK, 1000000 rows affected (10.67 sec)
Records: 1000000 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (1.17 sec)
しかし、7mioバッチを実行しても、結果は同じように見えますが、iostat -mdx sda sdb 5
では、30秒間100%の使用率があります:
mysql> insert into widgetuser select * from widgetuser_tmp limit 7000000,1000000;flush tables;
Query OK, 1000000 rows affected (10.73 sec)
Records: 1000000 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (1.21 sec)
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
sda 0.00 88.60 0.00 295.60 0.00 1.52 10.53 130.60 435.93 3.38 100.00
sdb 0.00 89.20 0.00 300.80 0.00 1.57 10.68 143.99 483.97 3.32 100.00
フラッシュ後にデータファイルは変更されません:
-rw-rw---- 1 mysql mysql 1032000000 2009-10-30 12:10 widgetuser.MYD
-rw-rw---- 1 mysql mysql 522777600 2009-10-30 12:11 widgetuser.MYI
また、テーブルの状態は正常にシームします:
+----------------+--------+---------+------------+----------+----------------+-------------+-------------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+-------------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+----------------+--------+---------+------------+----------+----------------+-------------+-------------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+-------------------+---------+
| widgetuser | MyISAM | 10 | Fixed | 8000000 | 129 | 1032000000 | 36310271995674623 | 522777600 | 0 | NULL | 2009-10-30 11:59:41 | 2009-10-30 12:10:59 | NULL | utf8_general_ci | NULL | delay_key_write=1 | |
+----------------+--------+---------+------------+----------+----------------+-------------+-------------------+--------------+-----------+----------------+---------------------+---------------------+------------+-----------------+----------+-------------------+---------+
そして、ドライブの使用率が100%であるため、続行すると、さらに悪化します:
mysql> insert into widgetuser select * from widgetuser_tmp limit 9000000,1000000;flush tables;
Query OK, 1000000 rows affected (31.93 sec)
Records: 1000000 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (2.34 sec)
mysql> insert into widgetuser select * from widgetuser_tmp limit 10000000,1000000;flush tables;
Query OK, 1000000 rows affected (2 min 39.72 sec)
Records: 1000000 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (7.82 sec)
主キーをチェックして、新しいエントリが一意かどうかを確認します。キーがメモリに収まらない(key_buffer_size = 512MB =約8Mioエントリ)とすぐに、不足しているキー部分をドライブ(-cache)からフェッチしてチェックする必要があります。したがって、読み取りが多くなり、挿入時間が遅くなります。キーがディスクキャッシュにバッファリングされるため、読み取りが遅くなることはありません。しかし私の質問:誰が突然そんなに書いているのか、どこで、なぜ、どうすれば修正できるのか?どんなアイデアでも大歓迎です!
さらなるアイデアと洞察:
- 1MB / sのランダム書き込みが完成したステートメントの後に続くため、一意の検証は既に渡されています
- これはahciをオンにしたソフトウェアraid-1で、ディスクは93%空きで、約80wMB / sの能力があります
- マシンには8GBのRAM、5GBのキャッシュ、MySQLが使用する600MB、1,7GBの空き容量があります
- MySQL 5.1.31-1ubuntu2-log
- delay_key_writeはこの動作を変更しません
- myisam_sort_buffer_size = 2 GB(ただし、ここでは使用しませんか?)
- key_buffer_size = 512 MB
- bin_logはオフです
- Linux 2.6.28-15-server#52-Ubuntu SMP Wed Sep 9 11:34:09 UTC 2009 x86_64 GNU / Linux
解決
あなたの質問から、あなたがどのような行動を期待しているのか、または得ているのかは完全には明らかではありません。ここに、あなたが知らないかもしれないものがいくつかあります
- FLUSH TABLESはMyISAMキーキャッシュを吹き飛ばします-ダーティブロックを書き込むだけでなく、クリーンブロックも破棄するため、すべてのインデックスブロックを再度フェッチして変更する必要があります
- MyISAMはデフォルトで1kのブロックサイズを使用しますが、これはおそらくファイルシステムブロックよりも小さいでしょう。これはパフォーマンスの問題を引き起こす可能性があります
- 何らかの耐久性を意図する場合(MyISAMを使用しているためと思われます)、コントローラーのバッテリーバックアップキャッシュでハードウェアRAIDを使用する必要があります。
推測では、インデックスがキーバッファに収まらないか、ブロックサイズの境界からバッファリングされていない書き込みであるため、さらに多くの書き込みを行う必要があります。
myisam_block_sizeを4k以上に変更して、テーブルを再構築します(これはmy.cnfのみのオプションで、再起動後に新しいテーブルでのみ有効になります)。
myisamchk -dvを使用して、テーブルのブロックサイズを調べることができます
他のヒント
i_mariadb5528を使用しています。key_buffer_size<!> gt; 90%を使用すると、delay_key_writeが機能しないようです。 そのため、key_buffer_sizeを2Gに拡大します。