MySQL có đảm bảo nâng cấp nguyên tử từ khóa đọc sang khóa ghi không?


2

Nếu một phiên khách hiện đang giữ khóa đọc (để cho phép đọc đồng thời trong khi đã ngăn ghi), và sau đó có được một khóa ghi trên cùng một bảng, MySQL có đảm bảo rằng khóa đó liên tục không?

Manual nêu rõ:

Nếu phiên phát hành câu lệnh LOCK TABLES để có được khóa trong khi đã giữ khóa, khóa hiện tại của khóa sẽ được giải phóng hoàn toàn trước khi khóa mới được cấp.

Và theo như tôi có thể thấy, nó không nói gì rõ ràng về việc "nâng cấp" một khóa từ đọc sang viết.Như trong

mysql> LOCK TABLE 'awesome' READ;
mysql> SELECT ... FROM 'awesome' ...
mysql> LOCK TABLE 'awesome' WRITE; # lock continuous, or dropped+reacquired?
mysql> INSERT INTO 'awesome' ...
mysql> UNLOCK TABLES;

Nếu tôi đang hoang tưởng về các thông báo trong tài liệu, tôi phải giả định rằng sẽ có một khoảnh khắc ngắn giữa hai trạng thái khóa mà phiên của tôi tạm thời không có khóa, trong đó phiên đồng thời có khả năng sửa đổi bảng, đưa nó vào trạng thái không phù hợp với những gì tôi đã thấy trong giai đoạn CHỌN.

Tôi không thể dựa vào các ngoại lệ được đưa ra bởi các vi phạm khóa trùng lặp, vì không có khóa duy nhất hữu ích (và nó có thể sẽ tăng gấp bốn lần kích thước của bảng nếu MySQL thậm chí còn hỗ trợ nó).Vì lý do tương tự, các giao dịch sẽ không thực sự giúp tôi, nhưng dù sao tôi cũng không thể sử dụng chúng, vì bảng trong câu hỏi đang sử dụng công cụ MyISAM vì lý do hiệu suất.Khóa thực sự có vẻ như đặt cược tốt nhất của tôi, chỉ có tài liệu có vẻ hơi dễ thấy trên các chi tiết chuyển tiếp.

Và những hiểu biết về cách MySQL bên trong xử lý việc chuyển từ khóa đọc sang khóa ghi nếu tập hợp các bảng giống nhau?

Tất nhiên, phương pháp búa gỗ lớn sẽ là phát hành một khóa ghi phía trước.Nhưng điều đó sẽ buộc tất cả các lựa chọn phải chờ đợi, rõ ràng.OTOH, theo tôi hiểu, một số lượng vô hạn các phiên có thể đọc cùng một bảng đồng thời (ngầm hoặc rõ ràng) mà không có ý nghĩa nào đối với hiệu suất được chọn cả.Điều duy nhất mà khóa đọc thực hiện là ngăn các bản cập nhật chạm vào bảng, đó chính xác là những gì tôi cần trong giai đoạn đầu tiên.

  0

Tại sao một khóa chính sẽ "tăng gấp bốn lần" kích thước của bảng? 19 may. 142014-05-19 11:46:15

  0

Đây không phải là khóa chính.PK là tự động.Khóa phụ là hàm băm nguyên.Thứ còn thiếu là một chỉ số duy nhất giả thuyết trên một cột văn bản nhỏ và tôi hy vọng rằng nó sẽ rất lớn cho dù là công cụ lưu trữ, nhưng đặc biệt là đối với InnoDB. Tôi nhận được id tự động tăng của tất cả những thứ tôi đã chèn trong hai ngày qua ".Kích thước bảng thông thường là ~ 520M hàng, ~ 75GB (mặc dù đã được chuyển đổi thành bảng TokuDB nén zlib, được thực hiện sau khi nội dung bảng là cuối cùng - nhanh hơn theo cách đó). 20 may. 142014-05-20 11:37:56

0

Thật vậy, phần hướng dẫn bạn trích dẫn thực hiện đúng như những gì nó nói:

-- Connection #1
LOCK TABLE mytable READ; -- lock is acquired

-- Connection #2
LOCK TABLE mytable WRITE; -- execution is suspended, lock is NOT acquired

-- Connection #1
LOCK TABLE mytable WRITE; -- execution is suspended
-- READ lock was released, allowing Connection #2 to acquire the WRITE lock
-- Connection #2 resumes

Giải pháp: chuyển sang InnoDB và sử dụng các giao dịch.Hiệu suất của động cơ InnoDB improved a lot in the recent versions .

-- Connection #1
BEGIN;
SELECT * FROM mytable LOCK IN SHARE MODE; -- lock is acquired

-- Connection #2
BEGIN;
SELECT * FROM mytable FOR UPDATE; -- execution is suspended, lock is NOT acquired

-- Connection #1
SELECT * FROM mytable FOR UPDATE;
-- deadlock is detected, Connection #2 is rolled back
  0

Đó là ... một bài kiểm tra hay và đơn giản.Cảm ơn!Không bao giờ xảy ra với tôi rằng tôi có thể tìm ra cách này.InnoDB chắc chắn không phải là một lựa chọn.Tôi đã thử và thử lại nhiều lần.TokuDB không phải là btw.Xây dựng các bảng theo định dạng MyISAM và sau đó chuyển đổi các công cụ trong bài vẫn nhanh hơn nhiều lần với khối lượng dữ liệu của chúng tôi. 20 may. 142014-05-20 11:41:16