Ý nghĩa của 'khóa rec nhưng không phải khoảng cách chờ' trong báo cáo bế tắc


12
  1. Về ý nghĩa của locks rec but not gap waitingGIAO DỊCH (1), cái nào đúng?

    • Đã được cấp khóa khoảng cách, chờ khóa X chỉ số cụm?
    • Đã được cấp khóa X chỉ mục cụm, chờ khóa khoảng cách?
  2. Có 31 hàng trong Giao dịch (1). Ý nghĩa của những hàng đó là gì? Điều này đại diện cho một khóa khoảng cách?

     0: len 4; hex 800c20d6; asc     ;;
     ....
     29: SQL NULL;
     30: SQL NULL;
    

Báo cáo DEADLOCK PHÁT HIỆN MỚI NHẤT

    LATEST DETECTED DEADLOCK
    ------------------------
    2015-09-25 15:27:24 1b8084000


    *** (1) TRANSACTION:
    TRANSACTION 5226928, ACTIVE 0 sec fetching rows
    mysql tables in use 1, locked 1
    LOCK WAIT 31 lock struct(s), heap size 6544, 548 row lock(s)
    MySQL thread id 71, OS thread handle 0x1b45be000, query id 4085356 localhost root Creating sort index
    SELECT  `rpush_notifications`.* FROM `rpush_notifications`  WHERE (processing = 0 AND delivered = 0 AND failed = 0 AND (deliver_after IS NULL OR deliver_after < '2015-09-25 07:27:24'))  ORDER BY created_at ASC LIMIT 100 FOR UPDATE


    *** (1) WAITING FOR THIS LOCK TO BE GRANTED:
    RECORD LOCKS space id 10287 page no 10901 n bits 152 index `PRIMARY` of table `ct_development`.`rpush_notifications` trx id 5226928 lock_mode X locks rec but not gap waiting
    Record lock, heap no 78 PHYSICAL RECORD: n_fields 31; compact format; info bits 0
     0: len 4; hex 800c20d6; asc     ;;
     1: len 6; hex 0000004fc1aa; asc    O  ;;
     2: len 7; hex 4c0000027b07fe; asc L   {  ;;
     3: len 30; hex 52707573683a3a436c69656e743a3a4163746976655265636f72643a3a41; asc Rpush::Client::ActiveRecord::A; (total 47 bytes);
     4: SQL NULL;
     5: len 30; hex 373838653836643365666465626262626639633464363261626433366132; asc 788e86d3efdebbbbf9c4d62abd36a2; (total 64 bytes);
     6: len 7; hex 64656661756c74; asc default;;
     7: len 7; hex 6869206d6f6d21; asc hi mom!;;
     8: len 13; hex 7b22666f6f223a22626172227d; asc {"foo":"bar"};;
     9: len 4; hex 80015180; asc   Q ;;
     10: len 1; hex 80; asc  ;;
     11: SQL NULL;
     12: len 1; hex 81; asc  ;;
     13: len 5; hex 99973276d8; asc   2v ;;
     14: SQL NULL;
     15: len 0; hex ; asc ;;
     16: SQL NULL;
     17: len 5; hex 99973276d6; asc   2v ;;
     18: len 5; hex 99973276d6; asc   2v ;;
     19: len 1; hex 80; asc  ;;
     20: SQL NULL;
     21: len 1; hex 80; asc  ;;
     22: SQL NULL;
     23: len 4; hex 80000002; asc     ;;
     24: len 4; hex 80000000; asc     ;;
     25: SQL NULL;
     26: SQL NULL;
     27: len 1; hex 80; asc  ;;
     28: SQL NULL;
     29: SQL NULL;
     30: SQL NULL;

    *** (2) TRANSACTION:

    TRANSACTION 5226922, ACTIVE 0 sec updating or deleting, thread declared inside InnoDB 0
    mysql tables in use 1, locked 1
    3 lock struct(s), heap size 1184, 2 row lock(s), undo log entries 1
    MySQL thread id 1446, OS thread handle 0x1b8084000, query id 4085345 localhost root updating
    UPDATE `rpush_notifications` SET processing = 0, delivered = 0, delivered_at = NULL, failed = 1, failed_at = '2015-09-25 07:27:24', error_code = NULL, error_description = '' WHERE `rpush_notifications`.`id` IN (794838, 794839)


    *** (2) HOLDS THE LOCK(S):
    RECORD LOCKS space id 10287 page no 10901 n bits 152 index `PRIMARY` of table `ct_development`.`rpush_notifications` trx id 5226922 lock_mode X locks rec but not gap
    Record lock, heap no 78 PHYSICAL RECORD: n_fields 31; compact format; info bits 0
     0: len 4; hex 800c20d6; asc     ;;
     1: len 6; hex 0000004fc1aa; asc    O  ;;
     2: len 7; hex 4c0000027b07fe; asc L   {  ;;
     3: len 30; hex 52707573683a3a436c69656e743a3a4163746976655265636f72643a3a41; asc Rpush::Client::ActiveRecord::A; (total 47 bytes);
     4: SQL NULL;
     5: len 30; hex 373838653836643365666465626262626639633464363261626433366132; asc 788e86d3efdebbbbf9c4d62abd36a2; (total 64 bytes);
     6: len 7; hex 64656661756c74; asc default;;
     7: len 7; hex 6869206d6f6d21; asc hi mom!;;
     8: len 13; hex 7b22666f6f223a22626172227d; asc {"foo":"bar"};;
     9: len 4; hex 80015180; asc   Q ;;
     10: len 1; hex 80; asc  ;;
     11: SQL NULL;
     12: len 1; hex 81; asc  ;;
     13: len 5; hex 99973276d8; asc   2v ;;
     14: SQL NULL;
     15: len 0; hex ; asc ;;
     16: SQL NULL;
     17: len 5; hex 99973276d6; asc   2v ;;
     18: len 5; hex 99973276d6; asc   2v ;;
     19: len 1; hex 80; asc  ;;
     20: SQL NULL;
     21: len 1; hex 80; asc  ;;
     22: SQL NULL;
     23: len 4; hex 80000002; asc     ;;
     24: len 4; hex 80000000; asc     ;;
     25: SQL NULL;
     26: SQL NULL;
     27: len 1; hex 80; asc  ;;
     28: SQL NULL;
     29: SQL NULL;
     30: SQL NULL;

    *** (2) WAITING FOR THIS LOCK TO BE GRANTED:
    RECORD LOCKS space id 10287 page no 7992 n bits 1480 index `index_rpush_notifications_multi` of table `ct_development`.`rpush_notifications` trx id 5226922 lock_mode X locks rec but not gap waiting
    Record lock, heap no 1279 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
     0: len 1; hex 80; asc  ;;
     1: len 1; hex 80; asc  ;;
     2: len 4; hex 800c20d6; asc     ;;

    *** WE ROLL BACK TRANSACTION (2)

Lược đồ bảng

CREATE TABLE `rpush_notifications` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `type` varchar(255) NOT NULL,
  `badge` int(11) DEFAULT NULL,
  `device_token` varchar(64) DEFAULT NULL,
  `sound` varchar(255) DEFAULT 'default',
  `alert` varchar(255) DEFAULT NULL,
  `data` text,
  `expiry` int(11) DEFAULT '86400',
  `delivered` tinyint(1) NOT NULL DEFAULT '0',
  `delivered_at` datetime DEFAULT NULL,
  `failed` tinyint(1) NOT NULL DEFAULT '0',
  `failed_at` datetime DEFAULT NULL,
  `error_code` int(11) DEFAULT NULL,
  `error_description` text,
  `deliver_after` datetime DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  `alert_is_json` tinyint(1) DEFAULT '0',
  `collapse_key` varchar(255) DEFAULT NULL,
  `delay_while_idle` tinyint(1) NOT NULL DEFAULT '0',
  `registration_ids` mediumtext,
  `app_id` int(11) NOT NULL,
  `retries` int(11) DEFAULT '0',
  `uri` varchar(255) DEFAULT NULL,
  `fail_after` datetime DEFAULT NULL,
  `processing` tinyint(1) NOT NULL DEFAULT '0',
  `priority` int(11) DEFAULT NULL,
  `url_args` text,
  `category` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_rapns_notifications_multi` (`app_id`,`delivered`,`failed`,`deliver_after`),
  KEY `index_rpush_notifications_multi` (`delivered`,`failed`)
) ENGINE=InnoDB AUTO_INCREMENT=337371 DEFAULT CHARSET=utf8;

Câu trả lời:


20

Câu hỏi 1: InnoDB đang cố gắng có được một khóa độc quyền trên hàng (thực ra đó là một khóa trên bản ghi chỉ mục được nhóm, PK), nhưng không phải là khoảng trống xung quanh (khóa khoảng cách). Bạn có thể đọc thêm về bản ghi và khóa khoảng cách tại đây: https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-record-locks

Yêu cầu khóa độc quyền đến từ mệnh đề "để cập nhật" được thêm vào câu lệnh SELECT. Hãy nhớ rằng khi sử dụng mức cô lập đọc lặp lại (chọn @@ session.tx_isolation), đó là mặc định, khóa độc quyền sẽ được đặt trên mỗi hàng được kiểm tra cho CHỌN, không chỉ các hàng được trả về (những thứ phù hợp tất cả các vị từ trong mệnh đề WHERE). Vì vậy, bạn có thể giảm số lượng hàng được kiểm tra và do đó các khóa được giữ sẽ giúp giảm đáng kể khả năng xảy ra xung đột, bằng cách sử dụng chỉ mục tổng hợp về: xử lý, phân phối, thất bại, phân phối sau đó

Tôi không biết cardinality (số lượng giá trị duy nhất) là gì cho các cột đó, nhưng bạn thường nên liệt kê chúng trong chỉ số tổng hợp từ cardinality cao nhất đến thấp nhất.

 

Câu hỏi 2: 31 là số lượng các trường trong bản ghi chỉ mục (hoặc hàng, theo logic) mà nó đang cố gắng / chờ đợi để có được một khóa độc quyền. InnoDB sử dụng PK phân cụm, do đó, các bản ghi trong chỉ mục được phân cụm (PK) chứa các trường cho mỗi cột do người dùng xác định - 29 trường trong trường hợp bảng Push_notifying của bạn: loại ... id - và luôn có thêm hai các trường bên trong cho mỗi bảng InnoDB: trường ID giao dịch 6 byte và trường con trỏ cuộn 7 byte (chúng được sử dụng cho MVCC). Vì vậy, 31 mục bạn thấy được liệt kê là các trường có trong bản ghi chỉ mục (hoặc hàng, theo logic) mà chúng tôi đang chờ khóa.

 

Chỉ cần FYI: Bạn có thể nhận thêm các phân tích về khóa InnoDB bằng cách sử dụng các bảng Information_Schema mới trong 5.6+: https://dev.mysql.com/doc/refman/5.7/en/innodb-inif-schema-transilities.html

Ngoài ra còn có một số báo cáo tuyệt vời trong lược đồ SYS mới, được bao gồm với máy chủ trong MySQL 5.7+ (chưa hoàn toàn đi vào hướng dẫn trực tuyến): https://github.com/MarkLeith/mysql-sys # innodb_lock_waits - xinnodb_lock_waits

Bạn có thể cài đặt lược đồ SYS mới nhất trong MySQL 5.6 theo cách thủ công, nếu nó được quan tâm: https://github.com/MarkLeith/mysql-sys/blob/master/sys_56.sql

Để biết thêm thông tin về nó: http://www.sl slideshoware.net/Leithal/performance-schema-and-sys-schema-in-mysql-57

 

Tôi hi vọng cái này giúp được!

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.