Ví dụ bế tắc của MySQL
Làm việc với cơ sở dữ liệu, kiểm soát tương tranh là khái niệm đảm bảo rằng các giao dịch cơ sở dữ liệu được thực hiện đồng thời mà không vi phạm tính toàn vẹn của dữ liệu Show Có rất nhiều lý thuyết và các cách tiếp cận khác nhau xung quanh khái niệm này và cách thực hiện nó, nhưng chúng tôi sẽ đề cập ngắn gọn đến cách PostgreSQL và MySQL (khi sử dụng InnoDB) xử lý nó và một vấn đề phổ biến có thể phát sinh trong các hệ thống đồng thời cao. bế tắc Các công cụ này thực hiện kiểm soát đồng thời bằng cách sử dụng một phương pháp có tên là MVCC (Kiểm soát đồng thời đa phiên bản). Trong phương pháp này, khi một mặt hàng đang được cập nhật, các thay đổi sẽ không ghi đè lên dữ liệu gốc mà thay vào đó, một phiên bản mới của mặt hàng (có các thay đổi) sẽ được tạo. Vì vậy, chúng tôi sẽ có một số phiên bản của mục được lưu trữ Một trong những ưu điểm chính của mô hình này là các khóa có được để truy vấn (đọc) dữ liệu không xung đột với các khóa có được để ghi dữ liệu và do đó, việc đọc không bao giờ chặn việc ghi và việc ghi không bao giờ chặn việc đọc Tuy nhiên, nếu một số phiên bản của cùng một mặt hàng được lưu trữ, giao dịch sẽ thấy phiên bản nào của mặt hàng đó? . Các giao dịch chỉ định một mức cách ly, xác định mức độ mà một giao dịch phải được cách ly khỏi các sửa đổi tài nguyên hoặc dữ liệu được thực hiện bởi các giao dịch khác. Mức độ này liên quan trực tiếp đến việc khóa do một giao dịch tạo ra và vì vậy, vì nó có thể được chỉ định ở cấp độ giao dịch, nên nó có thể xác định tác động mà một giao dịch đang chạy có thể có đối với các giao dịch đang chạy khác Đây là một chủ đề rất thú vị và dài, mặc dù chúng tôi sẽ không đi vào quá nhiều chi tiết trong blog này. Chúng tôi muốn giới thiệu tài liệu chính thức của PostgreSQL và MySQL để đọc thêm về chủ đề này Vì vậy, tại sao chúng ta lại đi sâu vào các chủ đề trên khi xử lý bế tắc? Có một số loại khóa (lại là một chủ đề dài và thú vị khác để xem xét cho PostgreSQL và MySQL), nhưng điều quan trọng về chúng là cách chúng tương tác (chính xác nhất là cách chúng xung đột) với nhau. Tại sao vậy? . Và một chi tiết không nhỏ, sau khi có được, khóa thường được giữ cho đến khi kết thúc giao dịch Đây là một ví dụ PostgreSQL về cách các loại khóa xung đột với nhau Xung đột các loại khóa PostgreSQL Và cho MySQL Các loại khóa MySQL xung đột X= khóa độc quyền IX= khóa độc quyền có ý định Vậy điều gì sẽ xảy ra khi tôi có hai giao dịch đang chạy muốn giữ các khóa xung đột trên cùng một đối tượng cùng một lúc? Vì vậy, bây giờ chúng tôi đang ở một vị trí để thực sự hiểu những gì đang xảy ra trong thời gian bế tắc Bế tắc là gì sau đó? Bế tắc cơ sở dữ liệu là tình huống trong đó hai hoặc nhiều giao dịch đang chờ nhau từ bỏ khóa Vì vậy, ví dụ, tình huống sau đây sẽ dẫn chúng ta đến bế tắc ví dụ bế tắc Tại đây, ứng dụng A nhận khóa trên bảng 1 hàng 1 để thực hiện cập nhật Đồng thời ứng dụng B bị khóa ở bàn 2 hàng 2 Lúc này ứng dụng A cần lấy khóa ở bàn 2 hàng 2 để tiếp tục thực hiện và kết thúc giao dịch nhưng không lấy được khóa do bị ứng dụng B giữ. Ứng dụng A cần đợi ứng dụng B giải phóng nó Nhưng ứng dụng B cần lấy khóa trên bàn 1 hàng 1 để tiếp tục thực hiện và kết thúc giao dịch nhưng không lấy được khóa do bị ứng dụng A nắm giữ Vì vậy, ở đây chúng ta đang ở trong một tình huống bế tắc. Ứng dụng A đang đợi tài nguyên do ứng dụng B nắm giữ để kết thúc và ứng dụng B đang đợi tài nguyên do ứng dụng A nắm giữ. Vì vậy, làm thế nào để tiếp tục? Hãy kiểm tra một số ví dụ bế tắc PostgreSQL và MySQL PostgreSQLGiả sử chúng ta có một thông tin từ các quốc gia trên thế giới
Chúng tôi có hai phiên muốn thay đổi cơ sở dữ liệu Phiên đầu tiên sẽ sửa đổi trường khu vực cho mã NLD và trường dân số cho mã AUS Phiên thứ hai sẽ sửa đổi trường khu vực cho mã AUS và trường dân số cho mã NLD Bảng dữ liệu
Phiên 1
buổi 2
Phiên 2 sẽ treo chờ Phiên 1 kết thúc Phiên 1
Ở đây chúng ta có bế tắc. Hệ thống đã phát hiện bế tắc và giết phiên 1 buổi 2
Và chúng tôi có thể kiểm tra xem phiên thứ hai đã kết thúc chính xác chưa sau khi phát hiện bế tắc và Phiên 1 đã bị hủy (do đó, khóa đã được giải phóng) Để biết thêm chi tiết, chúng ta có thể xem nhật ký trong máy chủ PostgreSQL của mình
Ở đây chúng ta sẽ có thể xem các lệnh thực tế đã được phát hiện khi bế tắc Tải xuống báo cáo trắng ngay hôm nay
Quản lý & Tự động hóa PostgreSQL với ClusterControl Tìm hiểu về những gì bạn cần biết để triển khai, giám sát, quản lý và thay đổi quy mô PostgreSQL Tải xuống báo cáo trắng mysqlĐể mô phỏng bế tắc trong MySQL, chúng ta có thể làm như sau Như với PostgreSQL, giả sử chúng ta có một cơ sở dữ liệu thử nghiệm với thông tin về diễn viên và phim trong số những thứ khác ________số 8_______Chúng tôi có hai quy trình muốn thay đổi cơ sở dữ liệu Quá trình đầu tiên sẽ sửa đổi trường first_name cho actor_id 1 và trường last_name cho actor_id 7 Quy trình thứ hai sẽ sửa đổi trường first_name cho actor_id 7 và trường last_name cho actor_id 1 Bảng dữ liệu
0Phiên 1 1 2 3buổi 2 1 2 6 7Phiên 2 sẽ treo chờ Phiên 1 kết thúc Phiên 1 8Ở đây chúng ta có bế tắc. Hệ thống đã phát hiện bế tắc và giết phiên 1 buổi 2 1 2 6 2Như chúng ta có thể thấy trong lỗi, như chúng ta đã thấy đối với PostgreSQL, có một bế tắc giữa cả hai quy trình Để biết thêm chi tiết, chúng ta có thể sử dụng lệnh SHOW ENGINE INNODB STATUSG . 3Dưới tiêu đề “ KHÓA CHẾT ĐƯỢC PHÁT HIỆN MỚI NHẤT “, chúng ta có thể xem chi tiết về bế tắc của mình. Để xem chi tiết về bế tắc trong nhật ký lỗi mysql, chúng tôi phải bật tùy chọn innodb_print_all_deadlocks trong cơ sở dữ liệu của mình 4Lỗi nhật ký MySQL 5Cân nhắc những gì chúng ta đã tìm hiểu ở trên về lý do xảy ra bế tắc, bạn có thể thấy rằng chúng ta không thể làm gì nhiều về phía cơ sở dữ liệu để tránh bế tắc. Dù sao, với tư cách là DBA, nhiệm vụ của chúng tôi là thực sự nắm bắt chúng, phân tích chúng và cung cấp phản hồi cho các nhà phát triển Thực tế là những lỗi này là đặc biệt đối với từng ứng dụng, vì vậy bạn sẽ cần kiểm tra từng lỗi một và không có hướng dẫn cho bạn biết cách khắc phục sự cố này. Hãy ghi nhớ điều này, có một số điều bạn có thể tìm kiếm Mẹo để điều tra và tránh bế tắcTìm kiếm các giao dịch dài hạn. Vì các khóa thường được giữ cho đến khi kết thúc một giao dịch, nên giao dịch càng dài thì các khóa trên tài nguyên càng lâu. Nếu có thể, hãy cố gắng chia các giao dịch dài hạn thành các giao dịch nhỏ hơn/nhanh hơn Đôi khi không thể thực sự chia nhỏ các giao dịch, vì vậy công việc nên tập trung vào việc cố gắng thực hiện các hoạt động đó theo thứ tự nhất quán mỗi lần, để các giao dịch tạo thành các hàng đợi được xác định rõ và không bị bế tắc Một giải pháp thay thế mà bạn cũng có thể đề xuất là thêm logic thử lại vào ứng dụng (tất nhiên, trước tiên hãy cố gắng giải quyết vấn đề cơ bản) theo cách mà nếu xảy ra bế tắc, ứng dụng sẽ chạy lại các lệnh đó Kiểm tra mức cô lập được sử dụng, đôi khi bạn thử bằng cách thay đổi chúng. Tìm các lệnh như CHỌN ĐỂ CẬP NHẬT và CHỌN ĐỂ CHIA SẺ , như . Một điều bạn có thể thử nếu không thể xóa các lệnh này là sử dụng mức cô lập thấp hơn, chẳng hạn như READ CAM KẾT . Tất nhiên, luôn thêm các chỉ mục được lựa chọn tốt vào bảng của bạn. Sau đó, các truy vấn của bạn cần quét ít bản ghi chỉ mục hơn và do đó đặt ít khóa hơn Ở cấp độ cao hơn, với tư cách là một DBA, bạn có thể thực hiện một số biện pháp phòng ngừa để giảm thiểu việc khóa nói chung. Ví dụ: trong trường hợp này là PostgreSQL, bạn có thể tránh thêm một giá trị mặc định trong cùng một lệnh mà bạn sẽ thêm một cột. Việc thay đổi bảng sẽ nhận được một khóa thực sự mạnh và việc đặt giá trị mặc định cho bảng sẽ thực sự cập nhật các hàng hiện có có giá trị null, khiến thao tác này mất nhiều thời gian. Vì vậy, nếu bạn chia thao tác này thành nhiều lệnh, thêm cột, thêm mặc định, cập nhật các giá trị null, bạn sẽ giảm thiểu tác động của khóa Tất nhiên, có rất nhiều mẹo như thế này mà các DBA có được khi thực hành (tạo chỉ mục đồng thời, tạo riêng chỉ mục pk trước khi thêm pk, v.v.), nhưng điều quan trọng là phải học và hiểu “cách Tóm lượcHy vọng rằng, blog này đã cung cấp cho bạn những thông tin hữu ích về bế tắc cơ sở dữ liệu và cách khắc phục chúng. Vì không có cách nào chắc chắn để tránh bế tắc, nên việc biết cách chúng hoạt động có thể giúp bạn nắm bắt chúng trước khi chúng gây hại cho các phiên bản cơ sở dữ liệu của bạn. Các giải pháp phần mềm như ClusterControl có thể giúp bạn đảm bảo rằng cơ sở dữ liệu của bạn luôn ổn định. ClusterControl đã giúp hàng trăm doanh nghiệp – doanh nghiệp của bạn sẽ là doanh nghiệp tiếp theo chứ? Bế tắc trong MySQL là gì?Bế tắc là tình huống trong đó các giao dịch khác nhau không thể tiến hành vì mỗi giao dịch giữ một khóa mà giao dịch kia cần . Bởi vì cả hai giao dịch đều đang đợi một tài nguyên có sẵn, nên không bao giờ giải phóng các khóa mà nó đang nắm giữ.
Làm cách nào để giải quyết bế tắc trong MySQL?Chỉ cần thử lại. Giữ các giao dịch nhỏ và trong thời gian ngắn để giúp chúng ít bị xung đột hơn . Cam kết giao dịch ngay sau khi thực hiện một loạt các thay đổi liên quan để làm cho chúng ít bị xung đột hơn. Đặc biệt, không để phiên mysql tương tác mở trong một thời gian dài với giao dịch không được cam kết.
Làm cách nào để tạo bế tắc trong MySQL?Ví dụ liên quan đến hai khách hàng, A và B. Tiếp theo, khách hàng B bắt đầu giao dịch và cố gắng xóa hàng khỏi bảng. mysql> BẮT ĐẦU GIAO DỊCH; . 00 giây) mysql> DELETE FROM t WHERE i = 1; Thao tác xóa yêu cầu khóa X.
Làm cách nào để mô phỏng bế tắc trong MySQL?Ví dụ bế tắc có 3 bước và tôi nghi ngờ bạn có thể đã bỏ lỡ bước cuối cùng. . T1. lựa chọn T2. xóa bỏ. T2 phải đợi T1 bây giờ. Chờ đợi có nghĩa là MySQL hiện vẫn nhìn thấy một cách khả thi mà cả T1 và T2 đều có thể kết thúc thành công. . T1. xóa bỏ. Điều này sẽ dẫn đến bế tắc trong T2 |