• 了解下Mysql的间隙锁及产生的原因


    什么是间隙锁
    当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(NEXT-KEY)锁。
    危害
    因为Query执行过程中通过范围查找的话,他会锁定整个范围内所有的索引键值,即使这个键值并不存在。
    间隙锁有一个比较致命的弱点,就是当锁定一个范围键值之后,即使某些不存在的键值也会被无辜的锁定,而造成在锁定的时候无法插入锁定值范围内的任何数据,在某些场景下这可能会针对性造成很大的危害。

    准备

    DROP TABLE IF EXISTS `innodb_lock`;
    CREATE TABLE `innodb_lock` (
      `a` int(10) NOT NULL,
      `b` varchar(255) NOT NULL DEFAULT '',
      KEY `index_a` (`a`),
      KEY `index_b` (`b`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    -- ----------------------------
    -- Records of innodb_lock
    -- ----------------------------
    INSERT INTO `innodb_lock` VALUES ('1', 'b2');
    INSERT INTO `innodb_lock` VALUES ('3', '3');
    INSERT INTO `innodb_lock` VALUES ('4', '4000');
    INSERT INTO `innodb_lock` VALUES ('5', '5000');
    INSERT INTO `innodb_lock` VALUES ('6', '6000');
    INSERT INTO `innodb_lock` VALUES ('7', '7000');
    INSERT INTO `innodb_lock` VALUES ('8', '8000');
    INSERT INTO `innodb_lock` VALUES ('9', '9000');
    INSERT INTO `innodb_lock` VALUES ('1', 'b1');
    MySQL [test_db]> select * from innodb_lock;
    +---+------+
    | a | b    |
    +---+------+
    | 1 | b2   |
    | 3 | 3    |
    | 4 | 4000 |
    | 5 | 5000 |
    | 6 | 6000 |
    | 7 | 7000 |
    | 8 | 8000 |
    | 9 | 9000 |
    | 1 | b1   |
    +---+------+

    注意表中的数据,a是int型,假如表示id,包含1,3,4,5,6,6...当然缺少2,没有连续下来。一般在公司里做云计算大数据分析最好是连续的,有可能有的公司数据很珍贵,所谓的删除其实是逻辑删除,只是做了状态更改。

    操作(打开两个Mysql终端,分别设置autocommit自动提交为0,也就是关闭自动提交功能,事务隔离级别处于可重复读状态)

    在第一个终端执行update操作,执行成功

    MySQL [test_db]> update innodb_lock set b = '1234' where a > 1 and a < 6; //也就是对1,3,4,5这四条数据做修改。注意这里没有2

    在第二个终端执行insert操作,发现被阻塞

    MySQL [test_db]> insert into innodb_lock values (2,'2000');

    反思:按说在InnoDB的行级锁,两个不同的终端操作不同的行数据,不会造成阻塞。可以看看这篇文章详细了解下http://www.cnblogs.com/wt645631686/p/8323963.html。但是阻塞出现了。

    接下来在第一个终端执行commit提交之后发现,第二个终端也执行成功了,然后第二个终端也commit提交。查询表数据,观察下数据的变化。

    MySQL [test_db]> select * from innodb_lock;
    +---+------+
    | a | b    |
    +---+------+
    | 1 | b2   |
    | 3 | 1234 |
    | 4 | 1234 |
    | 5 | 1234 |
    | 6 | 6000 |
    | 7 | 7000 |
    | 8 | 8000 |
    | 9 | 9000 |
    | 1 | b1   |
    | 2 | 2000 |
    +---+------+

    通过最开始的介绍和案例操作,也就是Mysql会宁可错杀也不会放过,没有无所谓,有就不放过,只要给定的范围,统统锁了。

  • 相关阅读:
    [LeetCode]题解(python):089-Gray Code
    [LeetCode]题解(python):088-Merge Sorted Array
    [LeetCode]题解(python):086-Partition List
    [LeetCode]题解(python):083-Remove Duplicates from Sorted List
    [LeetCode]题解(python):082-Remove Duplicates from Sorted List II
    [LeetCode]题解(python):081-Search in Rotated Sorted Array II
    [LeetCode]题解(python):080-Remove Duplicates from Sorted Array II
    [LeetCode]题解(python):079-Word Search
    [LeetCode]题解(python):078-Subsets
    软件开发冲刺5
  • 原文地址:https://www.cnblogs.com/wt645631686/p/8324671.html
Copyright © 2020-2023  润新知