2012-10-12 39 views
5

Chúng tôi đã trải qua một sự cố chậm lớn trong hiệu suất UPDATE trên cơ sở dữ liệu của chúng tôi.MySQL/InnoDB đôi khi một số cập nhật chạy rất chậm, trong trạng thái 'Đang cập nhật'

Ví dụ, bảng FooTable chúng tôi có khoảng 40 cột với một PK varchar ngoài ra còn có 10 chỉ mục. Các truy vấn sau đây mất 44 giây, trong khi ở những thời điểm khác nó chạy hầu như ngay lập tức. Trong thời gian chậm lại tải trung bình trên máy chủ là khá thấp (1,5 cho 5 phút trung bình) và IO theo vmstat là khá hợp lý là tốt.

Dưới đây là một ví dụ:

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) 

Đối với những gì nó có giá trị truy vấn ví dụ trên đã được chạy trên một bảng InnoDB được 'xây dựng lại' (ALTER TABLE FooTable ENGINE = InnoDB;) ít hơn một tuần trước đây. Ban đầu tôi nghi ngờ rằng điều này liên quan đến các vấn đề hiệu suất được biết đến của InnoDB với các PK không liên tục/không tuần tự, tuy nhiên chúng ta có các bảng khác sử dụng các PK tuần tự và đã thấy cùng các vấn đề.

Đây là trên một máy chủ sản xuất: Centos 5 2.6.18-238.19.1.el5 x86_64 MySQL/Percona 5.1.57-rel12.8-log 96GB bộ nhớ với 58.8G dữ liệu lan rộng khắp 87 bảng

Các thiết lập InnoDB có liên quan như sau:

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 

tôi không sử dụng FORMAT = NÉN trên bảng này, tuy nhiên tôi vào người khác.

Bất kỳ đề xuất nào về cách tìm hiểu những gì đang xảy ra trong giai đoạn Cập nhật mất quá nhiều thời gian?

+0

'EXPLAIN' có hoạt động với' UPDATE' không? Bạn có nhận được cùng một hiệu suất với 'SELECT BarColumn FROM FooTable WHERE varCharPK = ...'? Tôi tự hỏi nếu nó làm điều gì đó kỳ lạ với các chỉ mục. –

+0

Bạn không thể chạy giải thích trên UPDATE, tuy nhiên nếu tôi chuyển đổi nó thành một SELECT có vẻ như nó cần, nó sử dụng chính CHÍNH, các hàng 1. – Jeremy

+0

Cố gắng thực hiện "SHOW PROCESSLIST" trong khi truy vấn đó đang chạy. Nó có thể hiển thị các truy vấn khác có khóa trên bàn. – bobwienholt

Trả lời

1

Nguyên nhân gốc dường như đã có các giao dịch ứng dụng đang chạy dài. Giải pháp là phá vỡ các giao dịch lớn thành các đơn vị công việc nhỏ hơn.

0

Làm thế nào về (chuyển đổi varcharPK thành văn bản và) bằng cách sử dụng chỉ mục băm trên trường varcharPK?

thay đổi bảng FooTable thêm KEY pk_index (varcharPK (100)) SỬ DỤNG HASH

Tôi có vấn đề tương tự một lần và điều này đã giúp. Tôi không chắc nó sẽ giúp bạn. Âm thanh giống như nó cũng sẽ hữu ích nếu bạn có thể chia bảng - nó có "quá nhiều" dữ liệu.

+0

Bạn có thể giải thích lý do đằng sau sự thay đổi này không? – Jeremy

+0

Sử dụng chỉ mục băm có ít không gian chỉ mục hơn và do đó sẽ nhanh hơn để tìm kiếm và duy trì. Kiểm tra này: http://stackoverflow.com/questions/12689460/how-to-index-innodb-text-in-mysql – viljun

+0

Ngoài ra văn bản không được lưu trữ với dữ liệu bảng (như varchar) và do đó nó cũng sẽ làm cho tất cả mọi thứ đi nhanh hơn. – viljun

Các vấn đề liên quan