2009-10-30 3 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) 

이 작성되는 동안, 그것은 바로 간다 15메가바이트/S, < 50 % 폴더의 유틸리티 디스크-1 RAID하고 우리는 내가 소스 테이블과 디스크 캐시를 작성하기 때문에 더는 읽어 볼 :

내가 다음 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 갑자기 우리는 30 초 동안 UTIL 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 = ca. 8Mio 항목), 검사를 위해 드라이브 (-cache)에서 빠진 키 부분을 가져와야합니다. 따라서 더 많은 읽기와 느린 삽입 시간을보아야합니다. 키가 디스크 캐시에 버퍼되어 있기 때문에 느린 읽기가 표시되지 않습니다. 하지만 내 질문 : 누가 갑자기 많이 쓰고 어디서, 왜 그리고 어떻게이 문제를 해결할 수 있습니까? 모든 아이디어를 높이 평가합니다!

학습과 아이디어와 통찰력 : 1MB의/s의 임의 쓰기 이후

  • 는 디스크는, 고유의 유효성 검사가 이미 AHCI에와 소프트웨어 RAID-1
  • 을 전달, 완성 된 문장을 따라 93 % 무료 및 무료 80wMB/s의 기계가 8 기가 바이트 램, 5기가바이트 캐시, 600메가바이트는 MySQL이 취한
  • , 1,7GB에 대해 할 수있는
  • MySQL의
  • DELAY_KEY_WRITE을 5.1.31-1ubuntu2 로그 이 동작을 변경하지 않습니다
  • myisam_sort_buffer_size = 2기가바이트 (하지만, 여기에 사용하지?)
  • key_buffer_size = 5백12메가바이트
  • bin_log 오프
  • 리눅스 2.6.28-15-서버 # 52 - 우분투 SMP 수요일입니다 9 월 9 일 11시 34 분 9 초 2009 년 x86_64 GNU/리눅스

답변

1

당신이 기대하거나 어떤 행동을하는지 분명하지 않습니다.여기에 몇 가지 당신이의 MyISAM 키 캐시를 압도

  • FLUSH 테이블을 모를 수도 있습니다 - 그냥 더러운 블록을 기록하지 않습니다, 또한 그렇게 모든 인덱스 블록이
  • 을 수정할 수 다시 가져올 수 있어야 깨끗한 사람을 무시합니다
  • MyISAM은 기본적으로 1K의 블록 크기를 사용합니다. 이는 아마도 파일 시스템 블록보다 작을 것입니다. 이것은 성능 문제를 야기 할 수 있습니다.
  • MyISAM을 사용하고 있기 때문에 어떤 종류의 내구성을 갖고 싶지 않다면 컨트롤러에 배터리 백업 캐시가있는 하드웨어 RAID를 사용해야합니다.

내 생각 엔 두 지수가 더 이상 키 버퍼에 맞는지, 또는 그들이 블록 크기 경계 해제 버퍼링 쓰기이기 때문에 읽는 트리거, 더 많은 쓰기를 할 필요가 있다는 없습니다.

myisam_block_size를 4k 이상으로 변경하고 테이블을 재구성하십시오 (재시작 후 새 테이블에만 적용되는 my.cnf-only 옵션).

당신과 함께 테이블에 블록 크기를 검사 할 수 있습니다 myisamchk를 -dv

+0

감사합니다. block_size를 확인해 드리겠습니다. 현재 1024입니다. 인덱스가 키 버퍼에 맞지 않지만 삽입이 커밋 된 후 추가 쓰기가 필요한 이유를 이해할 수 없습니다. 읽고 느린 삽입뿐만 아니라, 이해할 수 있지만 두 번째 iostat 덤프에서 볼 수있는 임의의 쓰기 이해할 수 없습니다! 감사합니다. – smint

0
key_buffer_size> 90 %의 사용, 그것은 그 DELAY_KEY_WRITE을 보이면 내가 너무 2G에 key_buffer_size를 확대 작동하지 않습니다, mariadb5528을 사용하고

.