cách để ngăn chặn các truy vấn chờ khóa cấp bảng


10

Chúng tôi đã gặp sự cố sau khi chuyển cơ sở dữ liệu của khách hàng sang một máy chủ bổ sung. Điều này sẽ có tác động tích cực đến hiệu suất của trang web, nhưng có một vấn đề với việc khóa bảng trong MyISAM. (Tôi đã nghe nói về việc sử dụng InnoDB thay vì MyISAM, nhưng chúng tôi không thể thay đổi công cụ trong tương lai gần).
Chúng tôi có thể phát hiện ra nó với một truy vấn cập nhật được thực hiện khi người điều hành kích hoạt nhận xét trên bài báo. Đây là quá trình:

  • truy vấn cập nhật được xử lý SET status = 1 WHERE id = 5(chỉ mục được đặt)
  • các tập tin lưu trữ của trang bị xóa

Tại thời điểm này, toàn bộ trang trở nên chậm. Cơ sở dữ liệu bận rộn trong vài phút. Tôi đã tìm nạp danh sách quy trình một vài lần và thấy khoảng 60 mục nhập của các truy vấn chọn khác nhau, tất cả đều ở trạng thái chờ khóa cấp bảng .

1. Tôi không unterstand tại sao bản cập nhật này trên bàn article_commentscó thể ảnh hưởng select-báo cáo cho bảng articleđể chờ khóa mức bảng. Trong danh sách quy trình, hầu hết tất cả các truy vấn đang chờ đều từ bảng này. Tôi đã đọc về thực tế rằng các cập nhật / chèn được ưu tiên lựa chọn và điều này có thể gây ra vấn đề như vậy, nhưng bản thân bảng bài viết không được cập nhật khi các bình luận được kích hoạt, vì vậy các lựa chọn không nên chờ đợi. Có phải tôi đã hiểu sai điều đó?
2. Có điều gì đó ngoài việc thay đổi sang InnoDB để ngăn chặn hành vi này hoặc ít nhất là để có được sự cân bằng tốt hơn? Tôi rất khó chịu về thực tế là vấn đề này đã không xuất hiện trước khi chuyển cơ sở dữ liệu sang máy chủ mới. Tôi đoán có một số cấu hình sai nhưng tôi không biết làm thế nào để xác định.


1
Cho phép ghi nhật ký chung và xem các câu lệnh THAM GIA giữa các bảng này. Khi bạn CHỌN nó sẽ tạo ra một LOCK READ ẩn. Vì MYISAM không hỗ trợ khóa ROW LEVEL, nên nó khóa ở cấp độ bảng. Có lẽ đó là trường hợp khóa này xảy ra trên máy chủ cũ nhưng không ai xem? So sánh dòng my.cnf của bạn cho dòng giữa các máy chủ và đặc biệt là đảm bảo key_buffer của bạn được điều chỉnh đúng.
ngẫu nhiên

Chúng tôi đã có một số vấn đề về hiệu suất khác trên máy chủ cũ và thường xem danh sách quy trình. Chủ yếu có nhiều quá trình ngủ, nhưng chúng tôi không bao giờ nhận thấy những người đang chờ đợi (tôi đã thấy thông tin này nói chung lần đầu tiên trên máy chủ mới này). Đồng nghiệp của tôi đã sao chép my.cnf cũ và điều chỉnh các giá trị sang phần cứng mới hiện có, nhưng không có nhiều mục. Tôi cũng đã so sánh kết quả đầu ra của "SHOW VARIABLES" nhưng thực sự không biết phải nhìn gì. Chúng tôi sẽ kiểm tra lại keybuffer vào ngày mai, cảm ơn vì nhận xét của bạn.
32 bitfloat

Gần đây chúng tôi đã có một vấn đề tương tự. Ban đầu chúng tôi key_buffer_sizeđã được thiết lập 1GB. Tăng điều đó để 10GBgiảm bớt vấn đề.
Haluk

@Rick James, cảm ơn bạn. Bạn đã cứu tôi rất nhiều rắc rối ngày hôm nay. Bạn có một danh sách mong muốn trong Amazon hoặc một nơi nào khác không? :) Tôi thiết lập query_cache_limit thành 1024. Hiện tại không có vấn đề khóa nào. Tôi đã làm điều đó trong các biến lúc đầu từ máy khách mysql. đặt truy vấn toàn cầu_cache_limit = 1024; Bây giờ tôi sẽ viết nó cho my.cnf. Giải pháp này đã cho tôi thời gian để lên kế hoạch di chuyển innodb mà không có bất kỳ căng thẳng nào vì vậy cảm ơn bạn.

Câu trả lời:


8

MyISAM Storage Engine nổi tiếng với việc thực hiện khóa toàn bộ bảng cho bất kỳ DML nào (CHỨNG MINH, CẬP NHẬT, XÓA). InnoDB chắc chắn sẽ giải quyết vấn đề đó trong dài hạn.

Tôi đã viết về ưu và nhược điểm của việc sử dụng MyISAM vs InnoDB

Đối với câu hỏi hiện tại của bạn, đây là một tình huống có thể xảy ra:

  • articlearticle_commentscả hai bảng MyISAM
  • article_commentscó một hoặc nhiều chỉ mục với statustư cách là một cột
  • Các cập nhật trang chỉ mục article_commentsđược lưu vào bộ đệm trong Bộ đệm khóa MyISAM (có kích thước bằng key_buffer_size ), khiến các trang chỉ mục cũ ra khỏi Bộ đệm khóa MyISAM
  • Bạn có các truy vấn CHỌN thực hiện THAM GIA giữa articlearticle_comments

Trong kịch bản được đề xuất của tôi, các CHỌN đối với articlebảng có thể được giữ lại để cho phép ghi vì phải chờ article_commentsđể không có bất kỳ DML nào (trong trường hợp này là một UPDATE)


Cảm ơn câu trả lời của bạn (và các liên kết), kịch bản của bạn là có thật. Tôi đã không nhận ra rằng hầu hết các bài viết được chọn thực sự tham gia vào bảng ý kiến ​​(hay nói cách khác, đã thấy các tuyên bố chưa hoàn chỉnh trong danh sách quy trình của phpmyadmin). Bạn có biết một giải pháp ngắn hạn để ngăn chặn nhiều truy vấn chờ đợi không? Tôi đã thử nó với "CẬP NHẬT THẤP HẤP DẪN" trong tuyên bố cụ thể nhưng điều đó không tạo ra những thay đổi đáng chú ý. Chúng tôi thực sự sẽ thay đổi thành innodb trong tương lai nhưng tôi tự hỏi liệu hiện tại có cách nào để cải thiện không.
32 bitfloat

Giải pháp cuối cùng: Chuyển đổi bảng thành InnoDB. Xem bài đăng của tôi dba.stackexchange.com/a/9422/877 về cách chuyển đổi mọi thứ MyISAM thành InnoDB
RolandoMyQueryDBA

7

Tại thời điểm này, toàn bộ trang trở nên chậm. Cơ sở dữ liệu bận rộn trong vài phút.

Có mùi như bạn có một Query_cache lớn?

mysql> SHOW VARIABLES LIKE 'query_cache%';
+------------------------------+----------+
| Variable_name                | Value    |
+------------------------------+----------+
| query_cache_limit            | 1048576  |
| query_cache_min_res_unit     | 4096     |
| query_cache_size             | 16777216 | -- Not over 50M
| query_cache_type             | DEMAND   | -- Only if using SQL_CACHE
| query_cache_wlock_invalidate | OFF      |
+------------------------------+----------+

Đối với các hệ thống sản xuất có nhiều ghi, bạn cũng có thể TẮT truy vấn_cache.

Tất cả các mục trong query_cache cho bảng đã cho sẽ bị xóa khi có bất kỳ ghi nào xảy ra với bảng đó. QC càng lớn, nhiệm vụ này càng chậm.

MyISAM sử dụng khóa "mức bảng". Đọc và ghi không thể xảy ra cùng một lúc (trên cùng một bảng). Thô, nhưng hiệu quả.


1
Vâng, vâng. Chúng tôi có khoảng 64M cachesize. Tuy nhiên, cảm ơn vì thông tin mới này đối với tôi, chúng tôi có cùng giá trị trên máy chủ cũ, nơi chúng tôi không nhận thấy các tablelockings. Chúng tôi đã bắt đầu chuyển sang InnoDB nhưng sự thật này vẫn còn là một bí ẩn ...
32bitfloat
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.