ความหมายของ 'ล็อคบันทึก แต่ไม่ต้องรอช่องว่าง' ในรายงานการหยุดชะงัก


12
  1. เกี่ยวกับความหมายของlocks rec but not gap waitingในธุรกรรม (1) ข้อใดที่ถูกต้อง?

    • ได้รับการล็อคช่องว่างรอดัชนี X คลัสเตอร์อยู่หรือไม่
    • ได้รับดัชนีดัชนี X lock แล้วรอการล็อคช่องว่างอยู่หรือไม่
  2. ธุรกรรมมี 31 แถว (1) ความหมายของแถวเหล่านั้นคืออะไร? สิ่งนี้แสดงถึงการล็อคช่องว่างหรือไม่?

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

รายงาน DEADLOCK ที่ตรวจพบล่าสุด

    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)

โครงสร้างตาราง

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;

คำตอบ:


20

คำถามที่ 1: InnoDB พยายามล็อกแบบเอกสิทธิ์เฉพาะบุคคลในแถว (จริง ๆ แล้วเป็นการล็อกในเรกคอร์ดดัชนีคลัสเตอร์ PK) แต่ไม่ใช่ช่องว่างโดยรอบ (ล็อคช่องว่าง) คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการบันทึกและการล็อคช่องว่างได้ที่นี่: https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-record-locks

คำขอล็อคแบบเอกสิทธิ์เฉพาะบุคคลมาจากคำสั่ง "for update" ที่เพิ่มลงในคำสั่ง SELECT โปรดทราบว่าเมื่อใช้ระดับการแยกแบบอ่านซ้ำได้ (select @@ session.tx_isolation) ซึ่งเป็นค่าเริ่มต้นการล็อคแบบเอกสิทธิ์จะถูกวางในทุกแถวที่ตรวจสอบสำหรับ SELECT ไม่ใช่เฉพาะระดับที่กลับมา เพรดิเคตทั้งหมดในส่วนคำสั่ง WHERE) ดังนั้นคุณอาจสามารถลดจำนวนแถวที่ตรวจสอบและทำให้การล็อกถูกล็อกซึ่งจะลดโอกาสของความขัดแย้งอย่างมากโดยใช้ดัชนีคอมโพสิตบน: การประมวลผลส่งมอบล้มเหลวส่งมอบ

ฉันไม่ทราบว่า cardinality (จำนวนค่าที่ไม่ซ้ำ) สำหรับคอลัมน์เหล่านั้น แต่โดยทั่วไปคุณควรแสดงรายการเหล่านี้ในดัชนีคอมโพสิตจาก cardinality สูงสุดถึงต่ำสุด

 

คำถามที่ 2: 31 คือจำนวนเขตข้อมูลในระเบียนดัชนี (หรือแถวอย่างมีเหตุผล) ที่มันพยายาม / รอเพื่อให้ได้การล็อคแบบเอกสิทธิ์ InnoDB ใช้ PK แบบคลัสเตอร์ดังนั้นบันทึกในดัชนีแบบกลุ่ม (PK) จะมีฟิลด์สำหรับแต่ละคอลัมน์ที่ผู้ใช้กำหนด - 29 ฟิลด์ในกรณีของตาราง push_notifications ของคุณ: id ... หมวดหมู่ - และจะมีสองเพิ่มเติมเสมอ เขตข้อมูลภายในสำหรับแต่ละตาราง InnoDB: เขตข้อมูล ID ธุรกรรม 6 ไบต์และเขตข้อมูลตัวชี้การหมุน 7 ไบต์ (ใช้สำหรับ MVCC) ดังนั้นรายการ 31 รายการที่คุณเห็นคือเขตข้อมูลที่อยู่ในบันทึกดัชนี (หรือแถวตามหลักเหตุผล) ที่เรากำลังรอการล็อค

 

เพียงแค่ FYI:คุณสามารถรับรายละเอียดเพิ่มเติมของการล็อก InnoDB โดยใช้ตาราง Information_Schema ใหม่ใน 5.6+: https://dev.mysql.com/doc/refman/5.7/en/innodb-information-schema-transactions.html

นอกจากนี้ยังมีรายงานที่ยอดเยี่ยมใน SYS schema ใหม่ซึ่งรวมอยู่ในเซิร์ฟเวอร์ใน MySQL 5.7+ (ยังไม่ได้ทำในคู่มือออนไลน์เลย): https://github.com/MarkLeith/mysql-sys # innodb_lock_waits - xinnodb_lock_waits

คุณสามารถติดตั้ง SYS schema ล่าสุดใน MySQL 5.6 ด้วยตนเองหากเป็นที่สนใจ: https://github.com/MarkLeith/mysql-sys/blob/master/sys_56.sql

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับมัน: http://www.slideshare.net/Leithal/performance-schema-and-sys-schema-in-mysql-57

 

ฉันหวังว่านี่จะช่วยได้!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.