一.根据案例二:不同索引加锁顺序的问题,模拟重现死锁(详细操作步骤)

  • 1.RR级别下,更新操作默认会加行级锁,行级锁会对索引加锁
  • 2.如果更新语句使用多个索引,行级锁会先锁定普通索引,再锁定聚簇索引
  • 3.如果两个SQL用到了不同的普通索引,或者一个用了,另外一个没用
  • 4.会导致这两个SQL加行级锁的顺序不一致,形成多个事物之间X锁的循环等待,形成死锁
1.1表结构
root@slave01 22:28:  [sqltest]> create table user_info (id int primary key,username varchar(20), status tinyint,key(username));
Query OK, 0 rows affected (0.03 sec)
#
root@slave01 22:54: [sqltest]> show create table user_info;
+-----------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-----------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| user_info | CREATE TABLE `user_info` (
`id` int(11) NOT NULL,
`username` varchar(20) DEFAULT NULL,
`status` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-----------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
#
insert into user_info values(1,'yzw1',1);
insert into user_info values(3,'yzw3',0);
insert into user_info values(5,'yzw5',1);
1.2执行计划
root@master 23:15:  [sqltest]> desc update user_info set status=1 where username='yzw3';
+----+-------------+-----------+------------+-------+---------------+----------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+----------+---------+-------+------+----------+-------------+
| 1 | UPDATE | user_info | NULL | range | username | username | 63 | const | 1 | 100.00 | Using where |
+----+-------------+-----------+------------+-------+---------------+----------+---------+-------+------+----------+-------------+
1 row in set (0.01 sec)
#
root@master 23:15: [sqltest]> desc update user_info set username='yzw33' where id=3;
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
| 1 | UPDATE | user_info | NULL | range | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | Using where |
+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
1 row in set (0.00 sec)
1.3重现
session 1 session 2
begin;
update user_info set status=1 where username='yzw3';
 
此时session除了给索引username加x锁,还给主键索引id=3的行记录加了x锁,但是这两个锁并不是同时获取的  
第一步先获取普通索引username上的X锁  
此时session 2进行更新 begin;
update user_info set username='yzw33' where id=3;
  session 2
第一步需要先获取聚簇索引,也就是主键索引上的X锁
第二步需要获取普通索引username上的X锁
  出现死锁ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
需要session 2的主键索引X锁 需要session 1的普通索引username X锁
root@master 23:11:  [(none)]> select * from information_schema.innodb_locks;
+-------------------+-------------+-----------+-----------+-----------------------+------------+------------+-----------+----------+-----------+
| lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data |
+-------------------+-------------+-----------+-----------+-----------------------+------------+------------+-----------+----------+-----------+
| 48736590:1135:3:3 | 48736590 | X | RECORD | `sqltest`.`user_info` | PRIMARY | 1135 | 3 | 3 | 3 |
| 48733648:1135:3:3 | 48733648 | X | RECORD | `sqltest`.`user_info` | PRIMARY | 1135 | 3 | 3 | 3 |
+-------------------+-------------+-----------+-----------+-----------------------+------------+------------+-----------+----------+-----------+
2 rows in set, 1 warning (0.00 sec)
1.4重现
  • 1.给status列增加索引
create index idx_status on user_info(status);
  • 2.执行计划,两条语句都是走的普通索引
root@master 23:26:  [sqltest]> desc update user_info set status=1 where username='yzw3';
+----+-------------+-----------+------------+-------+---------------+----------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+----------+---------+-------+------+----------+-------------+
| 1 | UPDATE | user_info | NULL | range | username | username | 63 | const | 1 | 100.00 | Using where |
+----+-------------+-----------+------------+-------+---------------+----------+---------+-------+------+----------+-------------+
1 row in set (0.04 sec)
#
root@master 23:29: [sqltest]> desc update user_info set username='yzw33' where status=0;
+----+-------------+-----------+------------+-------+---------------+------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+------------+---------+-------+------+----------+-------------+
| 1 | UPDATE | user_info | NULL | range | idx_status | idx_status | 2 | const | 1 | 100.00 | Using where |
+----+-------------+-----------+------------+-------+---------------+------------+---------+-------+------+----------+-------------+
1 row in set (0.01 sec)
  • 3.两个会话更新索引

    session 1 session 2
    begin;
    update user_info set status=1 where username='yzw3';
     
    第一步已经获取了username的普通索引X锁 begin;
    update user_info set username='yzw33' where status=0;
      第一步已经获取status的普通索引X锁
    第二步给主键索引加X锁
    第二步需要给主键索引加X锁,无法获取 出现死锁ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
      因为要更新非主键索引username,因此要给username加X锁,但是无法获取
    root@master 23:30:  [sqltest]> select * from information_schema.innodb_locks;
    +-------------------+-------------+-----------+-----------+-----------------------+------------+------------+-----------+----------+-----------+
    | lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data |
    +-------------------+-------------+-----------+-----------+-----------------------+------------+------------+-----------+----------+-----------+
    | 48739611:1135:5:2 | 48739611 | X | RECORD | `sqltest`.`user_info` | idx_status | 1135 | 5 | 2 | 0, 3 |
    | 48738737:1135:5:2 | 48738737 | X | RECORD | `sqltest`.`user_info` | idx_status | 1135 | 5 | 2 | 0, 3 |
    +-------------------+-------------+-----------+-----------+-----------------------+------------+------------+-----------+----------+-----------+
    2 rows in set, 1 warning (0.00 sec)
1.5多查询一次取主键,解决死锁
begin;
update user_info set status=1 where id in (select id from (select id from user_info where username='yzw3') t);
begin;
update user_info set username='yzw33' where id in (select id from (select id from user_info where status=0) t);
root@master 23:56:  [sqltest]> select * from information_schema.innodb_locks;
+-------------------+-------------+-----------+-----------+-----------------------+------------+------------+-----------+----------+-----------+
| lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data |
+-------------------+-------------+-----------+-----------+-----------------------+------------+------------+-----------+----------+-----------+
| 48744368:1135:3:3 | 48744368 | X | RECORD | `sqltest`.`user_info` | PRIMARY | 1135 | 3 | 3 | 3 |
| 48744353:1135:3:3 | 48744353 | X | RECORD | `sqltest`.`user_info` | PRIMARY | 1135 | 3 | 3 | 3 |
+-------------------+-------------+-----------+-----------+-----------------------+------------+------------+-----------+----------+-----------+
2 rows in set, 1 warning (0.00 sec)
> 依然存在死锁,因为都给主键id加了X锁

二.根据方案三:TMS死锁分析和处理,模拟重现死锁(详细操作步骤)

  • 1.构造数据
create table user_info1 (id int primary key,name varchar(10), level tinyint);
insert into user_info1 values(1,'AA',0);
insert into user_info1 values(3,'CC',0);
insert into user_info1 values(5,'EE',2);
insert into user_info1 values(7,'GG',5);
insert into user_info1 values(9,'GG',7);
insert into user_info1 values(11,'JJ',20);
session 1 >select * from user_info1;
+----+------+-------+
| id | name | level |
+----+------+-------+
| 1 | AA | 0 |
| 3 | CC | 0 |
| 5 | EE | 2 |
| 7 | GG | 5 |
| 9 | GG | 7 |
| 11 | JJ | 20 |
+----+------+-------+
6 rows in set (0.00 sec)
  • 2.过程

    session 1 session 2
      begin;
    insert into user_info1 values(2,'BB',1);
    delete from user_info1 where name='BB';
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
    此时是RC级别 session 2首先插入数据并给这一行加X锁,因为没有索引,同时在两边加gap锁
    delete from user_info1 where name='BC';
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
     
    delete from user_info1 where level=8;
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
     
    delete where条件没有索引,会对整表扫描并加gap锁,但是此时session2已经加了gap锁,session1的delete事务被回退  
    delete from user_info1 where  name='BB'
    ------- TRX HAS BEEN WAITING 10 SEC FOR THIS LOCK TO BE GRANTED:
    RECORD LOCKS space id 1137 page no 3 n bits 80 index PRIMARY of table `sqltest`.`user_info1` trx id 48906774 lock_mode X locks rec but not gap waiting
    Record lock, heap no 8 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
  • 3保持RCset tx_isolation='READ-COMMITTED';级别,增加索引

    session 1 >create index idx_name_level on user_info1(name,level);
    Query OK, 0 rows affected (0.12 sec)
    Records: 0 Duplicates: 0 Warnings: 0
    session 1 session 2
      begin;
    insert into user_info1 values(2,'BB',1);
    delete from user_info1 where name='BB';
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
    此时是RC级别 session 2首先插入数据并加gap锁,
    session 1 >delete from user_info1 where name='BC';
    Query OK, 0 rows affected (0.00 sec)
    RC级别下,增加了索引,没有了gap锁
    session 1 >delete from user_info1 where name='BB';
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
    session 1 >delete from user_info1 where level=8;
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
    session 1 >delete from user_info1 where level=20;
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
    session 1 >delete from user_info1 where level=7;
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
    session 1 >delete from user_info1 where level=2;
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
    索引(a,b),如果where字段使用了索引a,则不存在gap锁了,猜测是单独使用索引b还是会存在gap锁,因为无法使用索引
    root@master 16:31:  [(none)]> select * from information_schema.innodb_locks;
    +-------------------+-------------+-----------+-----------+------------------------+------------+------------+-----------+----------+-----------+
    | lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data |
    +-------------------+-------------+-----------+-----------+------------------------+------------+------------+-----------+----------+-----------+
    | 48942672:1137:3:8 | 48942672 | X | RECORD | `sqltest`.`user_info1` | PRIMARY | 1137 | 3 | 8 | 2 |
    | 48942589:1137:3:8 | 48942589 | S | RECORD | `sqltest`.`user_info1` | PRIMARY | 1137 | 3 | 8 | 2 |
    +-------------------+-------------+-----------+-----------+------------------------+------------+------------+-----------+----------+-----------+
    2 rows in set, 1 warning (0.00 sec)
  • 4增加索引(b),验证

session 1 >create index idx_level on user_info1(level);
Query OK, 0 rows affected (0.08 sec)
Records: 0 Duplicates: 0 Warnings: 0
session 1 | session 2
---|---
&nbsp; | begin;</br>insert into user_info1 values(2,'BB',1);
delete from user_info1 where name='BB';</br>ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction | 此时是RC级别 session 2首先插入数据并加X锁
session 1 >delete from user_info1 where name='BC';</br>Query OK, 0 rows affected (0.00 sec)</br>session 1 >delete from user_info1 where name='BB';</br>ERROR 1205 (HY000): Lock wait timeout xceeded; try restarting transaction</br>session 1 >delete from user_info1 where level=8;</br>Query OK, 0 rows affected (0.01 sec)</br>session 1 >delete from user_info1 where level=20;</br>Query OK, 1 row affected (0.01 sec)</br>session 1 >delete from user_info1 where level=7;</br>Query OK, 1 row affected (0.00 sec)</br>session 1 >delete from user_info1 where level=2;</br>Query OK, 1 row affected (0.00 sec)</br>|此时b有了索引,RC级别下也就不存在gap锁了
  • 5更改为RR级别set tx_isolation='REPEATABLE-READ';,先使用索引(a,b)
session 2 >drop index idx_level on user_info1;
Query OK, 0 rows affected (0.16 sec)
Records: 0 Duplicates: 0 Warnings: 0
session 2 >begin;
Query OK, 0 rows affected (0.00 sec)
#
session 2 >insert into user_info1 values(2,'BB',1);
Query OK, 1 row affected (0.00 sec)
#
session 1 >delete from user_info1 where name='BB';
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
session 1 >delete from user_info1 where name='BC';
Query OK, 0 rows affected (0.00 sec)
#
session 1 >delete from user_info1 where level=8;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
session 1 >delete from user_info1 where level=2;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
session 1 >delete from user_info1 where name='CB';
Query OK, 0 rows affected (0.00 sec)
#
session 1 >delete from user_info1 where name='BA';
Query OK, 0 rows affected (0.00 sec)
  • 6总结
  1. RC和RR级别下如果更新没有索引的字段,会加gap锁
  2. 必须能用上索引,(a,b)只用b是无效索引
  3. RC增加了索引后就不存在gap锁了
  4. RR级别在没有索引的情况,用不上索引也会产生gap锁
  5. 解决方法,最好使用RC级别+索引,或者RR下修改参数innodb_locks_unsafe_for_binlog=on
  6. 间隙锁只会block住insert操作
session 1 >select * from user_info1;
+----+------+-------+
| id | name | level |
+----+------+-------+
| 1 | AA | 0 |
| 3 | BA | 1 |
| 5 | EE | 2 |
| 7 | GG | 5 |
| 9 | GG | 7 |
| 11 | JJ | 20 |
+----+------+-------+
6 rows in set (0.00 sec)
#
session 1 >begin;
Query OK, 0 rows affected (0.00 sec)
#
session 1 >update user_info1 set level=3 where name='BA';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
session 2 >begin;
Query OK, 0 rows affected (0.01 sec)
#
session 2 >insert into user_info1 values(2,'AB',1);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

三.根据案例四:MySQL间隙锁导致的Deadlock分析,模拟重现死锁(详细操作步骤)

3.1 造数据
create table t3 (id int auto_increment,coupon_id int,uid int,is_inuse tinyint,primary key(id),key (coupon_id,uid));
insert into t3 (coupon_id,uid,is_inuse) values(16,160825,1);
insert into t3 (coupon_id,uid,is_inuse) values(16,160835,1);
insert into t3 (coupon_id,uid,is_inuse) values(16,160845,1);
insert into t3 (coupon_id,uid,is_inuse) values(16,160855,1);
insert into t3 (coupon_id,uid,is_inuse) values(16,160865,1);
root@master 22:56: [sqltest]> select * from t3;
+----+-----------+--------+----------+
| id | coupon_id | uid | is_inuse |
+----+-----------+--------+----------+
| 1 | 16 | 160825 | 1 |
| 2 | 16 | 160835 | 1 |
| 3 | 16 | 160845 | 1 |
| 4 | 16 | 160855 | 1 |
| 5 | 16 | 160865 | 1 |
+----+-----------+--------+----------+
5 rows in set (0.00 sec)
3.2 行记录两边间隙锁范围内无法插入
  • 1.session 1给id=3的行记录加X锁,同时加间隙锁:160835160845,160845160855
set tx_isolation='REPEATABLE-READ';
set autocommit=0;
start transaction;
select * from t3 where (uid=160845 and coupon_id=16 and is_inuse=1) for update;
+----+-----------+--------+----------+
| id | coupon_id | uid | is_inuse |
+----+-----------+--------+----------+
| 3 | 16 | 160845 | 1 |
+----+-----------+--------+----------+
1 row in set (0.00 sec)
  • 2.session 2插入记录,在间隙范围:160835~160845
set tx_isolation='REPEATABLE-READ';
set autocommit=0;
start transaction;
insert into t3 (coupon_id,uid,is_inuse) values (16,160840,1);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
  • 3.lock
root@master 23:08:  [sqltest]> select * from information_schema.innodb_locks;
+-------------------+-------------+-----------+-----------+----------------+------------+------------+-----------+----------+---------------+
| lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data |
+-------------------+-------------+-----------+-----------+----------------+------------+------------+-----------+----------+---------------+
| 49020303:1139:4:4 | 49020303 | X,GAP | RECORD | `sqltest`.`t3` | coupon_id | 1139 | 4 | 4 | 16, 160845, 3 |
| 49020011:1139:4:4 | 49020011 | X | RECORD | `sqltest`.`t3` | coupon_id | 1139 | 4 | 4 | 16, 160845, 3 |
+-------------------+-------------+-----------+-----------+----------------+------------+------------+-----------+----------+---------------+
2 rows in set, 1 warning (0.00 sec)
  • 4.session 2插入记录,在间隙范围:160845~160855
set tx_isolation='REPEATABLE-READ';
set autocommit=0;
start transaction;
insert into t3 (coupon_id,uid,is_inuse) values (16,160850,1);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
  • 5.lock
root@master 23:11:  [sqltest]> select * from information_schema.innodb_locks;
+-------------------+-------------+-----------+-----------+----------------+------------+------------+-----------+----------+---------------+
| lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data |
+-------------------+-------------+-----------+-----------+----------------+------------+------------+-----------+----------+---------------+
| 49022356:1139:4:5 | 49022356 | X,GAP | RECORD | `sqltest`.`t3` | coupon_id | 1139 | 4 | 5 | 16, 160855, 4 |
| 49020011:1139:4:5 | 49020011 | X,GAP | RECORD | `sqltest`.`t3` | coupon_id | 1139 | 4 | 5 | 16, 160855, 4 |
+-------------------+-------------+-----------+-----------+----------------+------------+------------+-----------+----------+---------------+
2 rows in set, 1 warning (0.00 sec)
3.3 行记录间隙锁范围外可以插入
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
session 2 >insert into t3 (coupon_id,uid,is_inuse) values (16,160860,1);
Query OK, 1 row affected (0.01 sec)
3.4 update不存在的记录,也会加间隙锁
  • 1.数据
session 1 >select * from t3;
+----+-----------+--------+----------+
| id | coupon_id | uid | is_inuse |
+----+-----------+--------+----------+
| 1 | 16 | 160825 | 1 |
| 2 | 16 | 160835 | 1 |
| 3 | 16 | 160845 | 1 |
| 4 | 16 | 160855 | 1 |
| 5 | 16 | 160865 | 1 |
+----+-----------+--------+----------+
5 rows in set (0.00 sec)
  • 2.update一条不存在的记录,此时gap锁范围:160835160845,160845160855
set tx_isolation='REPEATABLE-READ';
set autocommit=0;
start transaction;
update t3 set is_inuse=0 where coupon_id=16 and uid=160845 and is_inuse=1;
  • 3.在间隙范围插入新值会产生死锁
set tx_isolation='REPEATABLE-READ';
set autocommit=0;
start transaction;
insert into t3 (coupon_id,uid,is_inuse) values (16,160840,1);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
  • 4.lock
root@master 23:11:  [sqltest]> select * from information_schema.innodb_locks;
+-------------------+-------------+-----------+-----------+----------------+------------+------------+-----------+----------+---------------+
| lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data |
+-------------------+-------------+-----------+-----------+----------------+------------+------------+-----------+----------+---------------+
| 49023844:1139:4:4 | 49023844 | X,GAP | RECORD | `sqltest`.`t3` | coupon_id | 1139 | 4 | 4 | 16, 160845, 3 |
| 49023813:1139:4:4 | 49023813 | X | RECORD | `sqltest`.`t3` | coupon_id | 1139 | 4 | 4 | 16, 160845, 3 |
+-------------------+-------------+-----------+-----------+----------------+------------+------------+-----------+----------+---------------+
2 rows in set, 1 warning (0.00 sec)
3.5删除索引,即使是间隙范围外的插入也会被block
  • 1.删除索引
session 2 >drop index coupon_id on t3;
Query OK, 0 rows affected (0.09 sec)
Records: 0 Duplicates: 0 Warnings: 0
#
session 2 >commit;
Query OK, 0 rows affected (0.00 sec)
  • 2.事务1加锁
set tx_isolation='REPEATABLE-READ';
set autocommit=0;
start transaction;
select * from t3 where (uid=160845 and coupon_id=16 and is_inuse=1) for update;
  • 3.事务2在间隙锁范围外插入,此时不是间隙锁,而是全表锁,无法插入
set tx_isolation='REPEATABLE-READ';
set autocommit=0;
start transaction;
select * from t3 where (uid=160850 and coupon_id=16 and is_inuse=1) for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
  • 4.lock
root@master 23:27:  [sqltest]> select * from information_schema.innodb_locks;
+-------------------+-------------+-----------+-----------+----------------+------------+------------+-----------+----------+-----------+
| lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data |
+-------------------+-------------+-----------+-----------+----------------+------------+------------+-----------+----------+-----------+
| 49025074:1139:3:2 | 49025074 | X | RECORD | `sqltest`.`t3` | PRIMARY | 1139 | 3 | 2 | 1 |
| 49025016:1139:3:2 | 49025016 | X | RECORD | `sqltest`.`t3` | PRIMARY | 1139 | 3 | 2 | 1 |
+-------------------+-------------+-----------+-----------+----------------+------------+------------+-----------+----------+-----------+
2 rows in set, 1 warning (0.00 sec)
3.6 总结
  • 1.RR级别下,有索引,更新的时候会给行加X锁,前后加GAP锁
  • 2.gap锁范围内无法插入新数据,避免产生幻读
  • 3.gap锁范围外可以正常插入新数据
  • 4.如果没有索引,更新的事务则加的就是全表锁了
  • 5.间隙内或者间隙外都无法插入新数据

MySQL 间隙锁的更多相关文章

  1. mysql 间隙锁专题

    本文研究记录mysql间隙锁,涉及以下情况 唯一索引 非唯一索引 范围更新 等值更新 mysql8 mysql7 RR RC 数据准备 mysql> select * from vodb.tes ...

  2. Mysql 间隙锁原理,以及Repeatable Read隔离级别下可以防止幻读原理(百度)

    Mysql知识实在太丰富了,前几天百度的面试官问我MySql在Repeatable Read下面是否会有幻读出现,我说按照事务的特性当然会有, 但是面试官却说 Mysql 在Repeatable Re ...

  3. 关于mysql 间隙锁

    前段时间系统老是出现update死锁,很是纠结.经过排查发现是间隙锁!间隙锁是innodb中行锁的一种, 但是这种锁锁住的却不止一行数据,他锁住的是多行,是一个数据范围.间隙锁的主要作用是为了防止出现 ...

  4. MySQL间隙锁问题

    间隙锁(Gap Lock):锁加在不存在的空闲空间,可以是两个索引记录之间,也可能是第一个索引记录之前或最后一个索引之后的空间. 最近用户反馈说系统老是出现insert时,等待超时了,最后发现是ins ...

  5. mysql间隙锁

    什么是间隙锁(gap lock)? 间隙锁是一个在索引记录之间的间隙上的锁. 间隙锁的作用? 保证某个间隙内的数据在锁定情况下不会发生任何变化.比如我mysql默认隔离级别下的可重复读(RR). 当使 ...

  6. mysql间隙锁 转

    前面一文 mysql锁 介绍了mysql innodb存储引擎的各种锁,本文介绍一下innodb存储引擎的间隙锁,就以下问题展开讨论 1.什么是间隙锁?间隙锁是怎样产生的? 2.间隙锁有什么作用? 3 ...

  7. Mysql innodb 间隙锁

    前段时间系统老是出现insert死锁,很是纠结.经过排查发现是间隙锁!间隙锁是innodb中行锁的一种, 但是这种锁锁住的却不止一行数据,他锁住的是多行,是一个数据范围.间隙锁的主要作用是为了防止出现 ...

  8. Mysql锁机制--间隙锁的危害

    Mysql 系列文章主页 =============== 1 准备数据 1.1 建表 DROP TABLE IF EXISTS employee; CREATE TABLE IF NOT EXISTS ...

  9. Mysql加锁过程详解(9)-innodb下的记录锁,间隙锁,next-key锁

    Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...

随机推荐

  1. VHD VHDX 区别

    A Virtual hard disk is saved either with VHD or VHDX file extension. VHD is the older while VHDX is ...

  2. Linux系统curl获取公网ip

    收集了几个查询当前公网ip的网址,可以通过curl命令方便的查看 curl cip.cc curl ipinfo.io curl myip.ipip.net curl http://members.3 ...

  3. jax-rs下载文件

    @Path("/file") public class FileService { private static final String FILE_PATH = "c: ...

  4. Linux命令(4):touch

    功能说明: touch命令参数可创建新文件以及更改文档或目录的日期时间,包括存取时间和更改时间. 命令格式: touch [选项]... 文件... 命令参数: -a   或--time=atime或 ...

  5. npm小工具、技巧合集:让你的npm“健步如飞”

    1.解决安装速度慢问题-nrm 解决痛点 由于npm的包仓库是在国外,npm包安装速度较慢,部分包甚至无法安装. 对比cnpm的优势 1.cnpm增加了大脑的记忆和思维负担,常常需要考虑使用npm还是 ...

  6. flex学习

            今天看视频学习的时候,发现css有一个 flex 的属性,非常的好用,为了让自己能够熟记,特意来分享一下flex的用法. 首先,采用Flex布局的元素,称为Flex容器(flex co ...

  7. ACM算法--枚举方法(指数枚举,组合枚举)模板

    // 递归实现指数型枚举 vector<int> chosen; void calc(int x) { if (x == n + 1) { for (int i = 0; i < c ...

  8. 服务器安装JDK

    1.卸载OpenJDK, 安装OracleJDK a.一般的LINUX发行版内置OpenJDK, 相当于JDK的开源版本(我们平时使用的JDK特指OracleJDK) b.OpenJDK 不能使用ja ...

  9. 前端——Vue.js学习总结一

    一.什么是Vue.js 1.Vue.js 是目前最火的一个前端框架,React是最流行的一个前端框架 2.Vue.js 是前端的主流框架之一,和Angular.js.React.js 一起,并成为前端 ...

  10. C. Coffee Break 贪心 思维 有点难 有意思

    C. Coffee Break 这个贪心之前好像写过,还是感觉挺难的,有点不会写. 这个题目大意是:给你一个数列n个元素,然后给你一天的时间,给你一个间隔时间d, 问你最少要用多少天可以把这个数列的所 ...