精华内容
下载资源
问答
  • mysql 行锁

    2019-05-23 10:03:05
    mysql行锁 说行锁钱先说一下锁分表锁还有行锁,这里重点说mysql行锁mysql行锁是通过索引来进行锁定的,目的是增大数据库并发能力,减少因为表锁造成的超时问题。但同时带来一个新问题就是容易造成死锁。所以...

    mysql行锁

    说行锁钱先说一下锁分表锁还有行锁,这里重点说mysql行锁。

    mysql行锁是通过索引来进行锁定的,目的是增大数据库并发能力,减少因为表锁造成的超时问题。但同时带来一个新问题就是容易造成死锁。所以使用时要注意。

    mysql行锁必须走索引,不然会走表锁,这是触发条件。

    行锁类型

    共享锁:也称读锁

    排它锁:也称写锁

    锁冲突

    共享锁和排它锁不可共存

    排它锁和任何锁不可共存

    如果数据1-5行被A上了共享锁,那么B还可以给1-5上共享锁,但是不能上排他锁。这时候数据可读,不可写

    但是如果1-5被A上了排他锁,那么B就无法给1-5上任何行锁。这时候数据可读不可写。

    死锁

    A锁了1-5行并请求6-10行数据,但是这时B锁了6-10,但又要请求1-5,这样就造成了死锁。

    死锁解决办法

    1,查看在锁的事务

    SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;

    2.杀死进程id(就是上面命令的trx_mysql_thread_id列)

    kill 线程ID

    展开全文
  • mysql行锁

    2020-03-08 19:06:57
    mysql行锁查询与释放:https://blog.csdn.net/luomao2012/article/details/93314380
    展开全文
  • MySQL行锁

    2020-10-31 16:53:56
    MySQL行锁 mysql锁的方式根据隔离级别不同而不同,因为默认隔离级别为repeatable-read可重复读,我们普遍理解为mysql锁实现方式为行锁,行锁就是利用索引实现完成的,mysql的支持的隔离级别有四种,这网上很多介绍,...

    MySQL行锁

    mysql锁的方式根据隔离级别不同而不同,因为默认隔离级别为repeatable-read可重复读,我们普遍理解为mysql锁实现方式为行锁,行锁就是利用索引实现完成的,mysql的支持的隔离级别有四种,这网上很多介绍,平常用的最多的也就是read-committed和repeatable-read两个,今天就对这两个隔离级别下锁的实现做下对比

    首先我们就用默认级别repeatable-read的隔离级别来做测试:

    mysql> CREATE TABLE `t1` (
        `id` int(11) NOT NULL AUTO_INCREMENT,
       `age1` int(11) DEFAULT NULL,
       `age2` int(11) DEFAULT NULL,
       PRIMARY KEY (`id`),
       KEY `age1` (`age1`)
      ) ENGINE=InnoDB;
    
    mysql> select * from t1;
    

    ±—±-----±-----+

    | id | age1 | age2 |

    ±—±-----±-----+

    | 1 | 1 | 2 |

    | 2 | 1 | 2 |

    | 3 | 1 | 2 |

    | 4 | 1 | 4 |

    | 5 | 1 | 2 |

    | 6 | 2 | 3 |

    ±—±-----±-----+

    创建了一个表t1,插入了部分数据,建立了age1的辅助索引,现在开两个session来做测试:

    session1	
    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)
    mysql> update t1 set age2=55 where age1=1 and id=2;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    rollback
    
    session2
    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)
    mysql>  update t1 set age2=55 where age1=1 and id=3;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    rollback
    

    看到这各位看官肯定觉得没问题,就应该是这样的啊,行锁嘛就是利用索引找到对应行进行加锁就好了,不急不急继续测试

    session1	
    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)
    mysql> update t1 set age2=55 where age1=1 and age2=4;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    rollback
    
    session2
    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)
    mysql> update t1 set age2=55 where age1=1 and id=1;
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
    rollback
    

    咦…这是咋回事呢?这更新的明显不是同一行为什么会被阻塞呢?我这暴脾气再用insert做下测试

    session1
    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)
    mysql> update t1 set age2=111 where age1=2 ;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    rollback
    
    session2
    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)
    mysql> insert into t1(age1,age2) values(1,33);
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
    rollback
    

    …出入数据和更新数据不是同一行业被阻塞了!好吧,来看下锁等待信息

    mysql> select * from innodb_lock_waits \G;
    
    *************************** 1. row ***************************
    
                    wait_started: 2016-04-07 15:35:00
    
                        wait_age: 00:00:08
    
                   wait_age_secs: 8
    
                    locked_table: `sbtest`.`t1`
    
                    locked_index: PRIMARY
    
                     locked_type: RECORD
    
                  waiting_trx_id: 33333
    
             waiting_trx_started: 2016-04-07 15:35:00
    
                 waiting_trx_age: 00:00:08
    
         waiting_trx_rows_locked: 1
    
       waiting_trx_rows_modified: 0
    
                     waiting_pid: 3
    
                   waiting_query: update t1 set age2=55 where age1=1 and id=1
    
                 waiting_lock_id: 33333:33:3:2
    
               waiting_lock_mode: X
    
       .....................................
    
    

    为了节约版面后面截就删掉了,这是上面两个update不同行被阻塞时的记录

    mysql> select * from innodb_lock_waits \G;
    
    *************************** 1. row ***************************
    
                    wait_started: 2016-04-07 15:40:43
    
                        wait_age: 00:00:26
    
                   wait_age_secs: 26
    
                    locked_table: `sbtest`.`t1`
    
                    locked_index: age1
    
                     locked_type: RECORD
    
                  waiting_trx_id: 33343
    
             waiting_trx_started: 2016-04-07 15:40:43
    
                 waiting_trx_age: 00:00:26
    
         waiting_trx_rows_locked: 1
    
       waiting_trx_rows_modified: 1
    
                     waiting_pid: 3
    
                   waiting_query: insert into t1(age1,age2) values(1,33)
    
                 waiting_lock_id: 33343:33:4:7
    
               waiting_lock_mode: X,GAP
    
          .......................................
    

    这个是insert时候的记录,第一个可以看出来是在等primary的X锁,但是根据记录我们可以查询出两个update的主键值应该是不同,session1查出来的id应该为4,session2直接指定的id为1,这明显不会一行啊,再来看看结合insert的锁等待情况,这个锁是在age1索引上,但是lock_mode多了一个GAP,这玩意是啥?好吧,只有挠着头皮去官方文档里找了:

    Gap lock: This is a lock on a gap between index records, or a lock on the gap before the first or after the last index record.
    
    原来msyql有间隙锁机制,就是把两个记录直接的缝缝给锁住,又或者锁住前后记录,在repeatable-read隔离级别下的mysql会有一个间隙锁算法,假如进行update扫描时,辅助索引有多个记录满足条件是会把这几条记录及记录中间的缝缝都会锁住,而insert的时候也会去判断下一个记录是否有加锁,所以才会发生上面的阻塞。这是mysql为了保证该隔离级别下的可重复读的机制,但也影响到业务并发的效率,可以修改系统参数innodb_locks_unsafe_for_binlog=on就可以关闭改间隙锁机制。该值默认为off,修改事务隔离级别为read-committed也可以避免间隙锁。修改为read-committed来试试看。
    
    mysql> set global tx_isolation=‘read-committed‘; 
    
    Query OK, 0 rows affected (0.00 sec)
    

    全部session连接重新连接一下才能生效,现在来按上面的步骤再测试一下:

    session1	
    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)
    mysql> update t1 set age2=55 where age1=1 and age2=4;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    rollback
    
    session2
    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)
    mysql> update t1 set age2=55 where age1=1 and id=1;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    rollback
    

    这个没问题…

    session1
    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)
    mysql> update t1 set age2=111 where age1=2;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    rollback
    
    session2
    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)
    mysql> insert into t1(age1,age2) values(1,33);
    Query OK, 1 row affected (0.00 sec)
    rollback	
    

    也没问题…

    mysql在默认隔离级别repeatable-read下,会有gap lock和next-key lock两个算法锁来确保数据可重复读

    Next-key lock: This is a combination of a record lock on the index record and a gap lock on the gap before the index record
    next-key lock就是范围锁,当我们利用索引范围扫描时,在这一个范围内的数据都会被加锁,以防止幻读。

    本文出自 “肖忠” 博客,请务必保留此出处http://xiaozhong991.blog.51cto.com/2354914/1761360

    展开全文
  • 锁是计算机协调多个进程或线程并发访问某一资源的机制。锁保证数据并发访问的一致性、有效性;锁冲突也是影响数据库并发访问性能的一个重要因素。...本文我们就重点来介绍MySQL行锁。行锁不同存储引擎的行锁实现...

    锁是计算机协调多个进程或线程并发访问某一资源的机制。锁保证数据并发访问的一致性、有效性;锁冲突也是影响数据库并发访问性能的一个重要因素。锁是Mysql在服务器层和存储引擎层的的并发控制。MySQL中从对数据操作的粒度分为表锁和行锁。表锁是指对一整张表加锁,一般是 DDL 处理时使用;而行锁则是锁定某一行或者某几行,或者行与行之间的间隙。本文我们就重点来介绍MySQL行锁。

    行锁不同存储引擎的行锁实现不同,后续没有特别说明,则行锁特指 InnoDB 实现的行锁。在了解 InnoDB 的加锁原理前,需要对其存储结构有一定的了解。InnoDB 是聚簇索引,也就是 B+树的叶节点既存储了主键索引也存储了数据行。而 InnoDB 的二级索引的叶节点存储的则是主键值,所以通过二级索引查询数据时,还需要拿对应的主键去聚簇索引中再次进行查询。

    行锁的模式有:读意向锁,写意向锁,读锁,写锁和自增锁(auto_inc),下面我们依次来看。

    1.读写锁

    读锁,又称共享锁(Share locks,简称 S 锁),加了读锁的记录,所有的事务都可以读取,但是不能修改,并且可同时有多个事务对记录加读锁。

    写锁,又称排他锁(Exclusive locks,简称 X 锁),或独占锁,对记录加了排他锁之后,只有拥有该锁的事务可以读取和修改,其他事务都不可以读取和修改,并且同一时间只能有一个事务加写锁。

    2.读写意向锁

    由于表锁和行锁虽然锁定范围不同,但是会相互冲突。所以当你要加表锁时,势必要先遍历该表的所有记录,判断是否加有排他锁。这种遍历检查的方式显然是一种低效的方式,MySQL 引入了意向锁,来检测表锁和行锁的冲突。意向锁也是表级锁,也可分为读意向锁(IS 锁)和写意向锁(IX 锁)。当事务要在记录上加上读锁或写锁时,要首先在表上加上意向锁。这样判断表中是否有记录加锁就很简单了,只要看下表上是否有意向锁就行了。意向锁之间是不会产生冲突的,也不和 AUTO_INC 表锁冲突,它只会阻塞表级读锁或表级写锁,另外,意向锁也不会和行锁冲突,行锁只会和行锁冲突。

    3.自增锁

    AUTOINC 锁又叫自增锁(一般简写成 AI 锁),是一种表锁,当表中有自增列(AUTOINCREMENT)时出现。当插入表中有自增列时,数据库需要自动生成自增值,它会先为该表加 AUTOINC 表锁,阻塞其他事务的插入操作,这样保证生成的自增值肯定是唯一的。AUTOINC 锁具有如下特点:

    1)AUTO_INC 锁互不兼容,也就是说同一张表同时只允许有一个自增锁;

    2)自增值一旦分配了就会 +1,如果事务回滚,自增值也不会减回去,所以自增值可能会出现中断的情况。

    显然,AUTOINC 表锁会导致并发插入的效率降低,为了提高插入的并发性,MySQL 从 5.1.22 版本开始,引入了一种可选的轻量级锁(mutex)机制来代替 AUTOINC 锁,可以通过参数 innodbautoinclockmode 来灵活控制分配自增值时的并发策略。

    行锁是MySQL数据库中非常重要的锁,行锁根据场景的不同又可以进一步细分,依次为 Next-Key Lock,Gap Lock 间隙锁,Record Lock 记录锁和插入意向 GAP 锁。不同的锁锁定的位置是不同的,比如说记录锁只锁住对应的记录,而间隙锁锁住记录和记录之间的间隔,Next-Key Lock 则所属记录和记录之前的间隙。想要了解这些行锁的详细信息,可以查看本站的MySQL教程,带你全面解析MySQL行锁。

    展开全文
  • Mysql 行锁

    2020-02-06 19:45:31
    行锁是在引擎层各个引擎自己实现的,并不是所有引擎都支持行锁,比如MyISAM就不支持行锁。 不支持行锁意味着并发控制只能使用表锁,对于这种引擎的表,同一表任何时刻只能由一个更新在运行。 两阶段锁 在InnoDB...
  • Mysql行锁

    2010-02-26 14:12:39
    Mysql行锁 mysql的innodb引擎是根据索引来实现行锁,如果你的查询没有通过索引,即进行的是表锁,上次mysql分享例子举的不充分,下面这个例子比较形象 Bug2671聚集程序多算了1秒,导致数据库锁阻塞,系统...
  • MySQL行锁是在引擎层由各个引擎自己实现的。但并不是所有的引擎都支持行锁,比如 MyISAM 引擎就不支持行锁。不支持行锁意味着并发控制只能使用表锁,对于这种引擎的表,同一张表上任何时刻只能有一个更新在执行,...
  • 一、mysql 行锁模拟1、mysql锁简单说明Mysql InnoDB行锁有2种,2者不能共存:共享锁Shared(S) lock,用于读取行记录互斥锁或叫排它锁Exclusive Lock (X),用于更新、删除行记录2、先模拟一个行锁。先用mysql命令框,...
  • 一文搞懂MySQL行锁、表锁、间隙锁详解2020-10-19 16:46:11前言我们前几篇讲了索引是什么,如何使用explain分析索引使用情况,如何去优化索引,以及show profiles分析SQL语句执行资源消耗的学习。今天我们来讲讲MySQL...
  • 行锁包括了共享锁、排他锁、间隙锁、记录锁、临键锁.共享锁是指,一个事务中如果开启了共享锁,其它事务也可以共享这个锁、所谓的共享就是指所有的线程、connection、会话、事务等都可以获得这个锁,都可以读取到加...
  • MYSql行锁

    2014-12-08 14:36:45
    数据库用的Mysql,现在想给某行加上数据读取锁,查了资料貌似Mysql只有行更新锁,读取的时候锁不了,请教下大神,告诉下解决办法[img=https://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/003/onion/18.gif]...
  • 做项目时由于业务逻辑的需要,必须对数据表的一行或多行加入行锁,举个最简单的例子,图书借阅系统。假设id=1的这本书库存为1,但是有2个人同时来借这本书,此处的逻辑为SELECT restnum FROM book WHERE id =1 ; --...
  • 通过本章内容,带你学习MySQL行锁,表锁,两种锁的优缺点,行锁变表锁的原因,以及开发中需要注意的事项。还在等啥?经验等你来拿!MySQL的存储引擎是从MyISAM到InnoDB,锁从表锁到行锁。后者的出现从某种程度上是...
  • 转载 :http://www.searchtb.com/2010/09/mysql%E8%A1%8C%E9%94%81%E6%B7%B1%E5%85%A5%E7%A0%94%E7%A9%B6-2.html做项目时由于业务逻辑的需要,必须对数据表的一行或多行加入行锁,举个最简单的例子,图书借阅系统。...
  • 行锁顾名思义,就是针对单行数据加锁,在mysql中,锁的实现是由引擎层实现的,MyISAM引擎就不支持行锁不支持行锁就意味着并发控制只能使用表锁,也就是说同一时间,在这个表上只能有一个更新在执行,这就会影响到业务...
  • 转载自:http://blog.csdn.net/minipeach/article/details/5325161/做项目时由于业务逻辑的需要,必须对数据表的一行或多行加入行锁,举个最简单的例子,图书借阅系统。假设id=1的这本书库存为1,但是有2个人同时来...
  • 做项目时由于业务逻辑的需要,必须对数据表的一行或多行加入行锁,举个最简单的例子,图书借阅系统。假设id=1的这本书库存为1,但是有2个人同时来借这本书,此处的逻辑为Selectrestnumfrombookwhereid=1;—如果...
  • 做项目时由于业务逻辑的需要,必须对数据表的一行或多行加入行锁,举个最简单的例子,图书借阅系统。假设id=1的这本书库存为1,但是有2个人同时来借这本书,此处的逻辑为Selectrestnumfrombookwhereid=1;--如果...
  • 问题描述当一个连接会话等待另外一个会话持有的互斥行锁时,就会发生行锁等待情况,行锁等待超时的报错如下。ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction问题原因通常情况下,持有...
  • 在调用存储过程中,就会涉及到表锁,行锁这一概念:所谓区别:有索引的时候就是行锁,没有索引的时候就是表索。innodb 的行锁是在有索引的情况下,没有索引的表是锁定全表的.表锁演示(无索引)Session1:mysql> set ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,176
精华内容 2,470
关键字:

mysql行锁

mysql 订阅