2009-10-30 37 views
2

我有以下查找表:的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) 

虽然是写作,它会直接到RAID-1与15MB /秒,盘UTIL < 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个百万行,这是所有罚款和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突然,我们有100%的util 30秒:

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)中提取缺失的关键部件以检查它。因此,我们应该看到更多的读取和更慢的插入时间 - 由于密钥缓存在磁盘缓存中,因此我们看不到较慢的读取。但我的问题:谁突然写这么多,在哪里,为什么,我该如何解决这个问题?任何想法表示赞赏!

Futher的想法和见解:

    因为1MB/s的随机写入
  • 遵循成品声明,独特的验证已经通过
  • 它是一个软件RAID-1 AHCI上,磁盘93%的游离,并且能够为约80wMB/s的
  • 机器已经8GB RAM,5GB缓存,600MB采取的MySQL,1,7GB自由
  • 的MySQL 5.1.31-1ubuntu2日志
  • 的DELAY_KEY_WRITE不改变这种行为
  • myisam_sort_buffer_size = 2 GB(这里没有使用,但是?)
  • 的key_buffer_size = 512 MB
  • bin_log熄灭
  • Linux的2.6.28-15服务器#52,Ubuntu的SMP星期三9月9日11:34:09 UTC 2009 x86_64 GNU/Linux

回答

1

从你的问题来看,你并没有完全清楚你期望或得到什么样的行为。这里有一些事情你可能不知道

  • FLUSH TABLES吹走了MyISAM键缓存 - 它不只是写脏块,它也丢弃干净的所以每一个索引块必须再次得到修改
  • 默认情况下,MyISAM使用的块大小为1k,可能小于文件系统块;这可能会产生性能问题
  • 如果您打算使用任何类型的耐久性(您大概不这样做,因为您使用的是MyISAM),那么您应该在控制器中使用具有电池备份缓存的硬件RAID。

我的猜测是要么索引不再适合关键缓冲区,要么它不得不做更多的写操作,这触发器读取,因为它们是无缓冲写入块大小的边界。

尝试将myisam_block_size更改为4k或更高版本并重建表(这是my.cnf-only选项,仅在重新启动后才对新表生效)。

您可以检查在表中的块大小用myisamchk -dv

+0

谢谢,我将检查block_size - 目前它是1024. 是索引不适合在关键缓冲区中,但我不明白为什么这需要额外写入_after_插入提交。读我会明白,插入速度较慢,但​​我不明白随机写入,你可以看到第二个iostat转储! 谢谢! – smint 2009-10-30 14:12:34

0

我使用mariadb5528,如果key_buffer_size的> 90%的使用率,似乎DELAY_KEY_WRITE不工作 所以扩大的key_buffer_size到2G 。