mysql锁

MySQL 5.7 InnoDB锁

久未见 提交于 2019-11-27 11:01:22
简介 参考https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-gap-locks。 InnoDB引擎实现了标准的行级别锁(S和X)。InnoDB引擎加锁原则遵循二段锁协议,即事务分为两个阶段,事务开始后进入加锁阶段,事务commit或者rollback就进入解锁阶段。InnoDB引擎下锁的影响因素很多,隔离级别不同,是否使用索引等都会产生不同的锁结果。 查看锁和事务 当出现ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction,要解决是一件麻烦的事情。特别是当一个SQL执行完了,但未COMMIT,后面的SQL想要执行就是被锁,超时后结束,DBA光从数据库无法着手找出源头是哪个SQL锁住了。有时候看看 show engine innodb status, 并结合 show full processlist 能暂时解决问题,但一直不能精确定位。在5.5中,information_schema 库中增加了三个关于锁的表(MEMORY引擎)。 INNODB_LOCKS 提供有关InnoDB事务已请求但尚未获得的以及事务正在阻塞另一个事务的锁的信息。 lock_id InnoDB内部的唯一锁ID lock_trx_id

mysql使用for update实现悲观锁

我们两清 提交于 2019-11-27 10:13:40
悲观缩: 顾名思义比较担心害怕,还没开始就怕出现并发,所以在处理sql之前就将表或具体数据给上锁。 使用for update测试 表数据 表结构 测试 1)sql: set autocommit=0; BEGIN; SELECT * FROM `user` WHERE `name`='zhangsan' for UPDATE; -- COMMIT; 1-1)结果 查询不受影响,整表都被锁住 2)sql: 2-1)结果 条件为主键时条件行被锁,查询不受影响 总结: 当for update的条件字段为索引或者主键的时候,只会锁住索引或者主键对应的行。 而当for update的字段为普通字段的时候,Innodb会锁住整张表。 查询不受影响 来源: https://www.cnblogs.com/lint20/p/11358372.html

mysql事务和锁 SELECT FOR UPDATE

核能气质少年 提交于 2019-11-27 09:27:35
事务: 当然有的人用begin /begin work .推荐用START TRANSACTION 是SQL-99标准启动一个事务。 start transaction #开始一个事务 操作 savepoint sp1 #保存点名称 操作 ROLLBACK ROLLBACK To sp1 #回退到 sp1点 commit 当用set autocommit = 0 的时候,你以后所有的sql都将作为事务处理,直到你用commit确认或 rollback结束,注意当你结束这个事务的同时也开启了新的事务!mysql 默认 autocommit=1,是自动提交的。 隔离级别 SQL标准定义的四个隔离级别为: 1.读未提交(Read Uncommitted):在READ COMMITED的事务隔离级别下,除了唯一性的约束检查以及外键约束的检查需要Gap Lock,InnoDB存储引擎不会使用Gap Lock的锁算法。这种隔离级别可以让当前事务读取到其它事物还没有提交的数据。这种读取应该是在回滚段中完成的。通过上面的分析,这种隔离级别是最低的,会导致引发脏读,不可重复读,和幻读。 2.读已提交(Read Committed):这种隔离级别可以让当前事务读取到其它事物已经提交的数据。通过上面的分析,这种隔离级别会导致引发不可重复读,和幻读。 3.可重复读取(Repeatable Read)

mysql 锁的粒度

醉酒当歌 提交于 2019-11-27 00:44:07
1、锁的类型分为读锁和写锁,这个很好区分。可以这样认为:如果有增删改,就是写锁。如果是查询,就是读锁。 2、锁的粒度也就是锁的范围,分为行锁和表锁。锁的范围和多个因素有关,包括事务隔离级别、是否使用索引。 测试 read-committed,结果是行锁 事务A: mysql> select @@session.tx_isolation; +------------------------+ | @@session.tx_isolation | +------------------------+ | READ-COMMITTED | +------------------------+ 1 row in set (0.00 sec) mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> update test set num=num+1 where id=1; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 事务B: mysql> select @@session.tx_isolation; +------------------------+ | @@session.tx_isolation |

MySQL加锁分析 (转)

谁说我不能喝 提交于 2019-11-26 16:28:07
参考: MySQL 加锁处理分析 。该文已经讲的很详尽了,也易懂,下面仅仅是个人做的总结。 一、 背景 1.1 隔离级别 1.2 加锁过程    逐条处理,逐条加锁。 1.3 两阶段锁2PL 1.4 gap锁   gap锁是间隙锁,即相邻两条有效记录间隙的锁(锁的是间隙),它是 针对insert的,用来解决幻读的发生。 它会阻塞insert,但不会阻塞delete/update等(记录本来也不存在)。   RC与RR的重要区别就是幻读。所以RR才需要引入gap锁。 二、加锁组合分析   说加什么锁,首先要了解两个前提:1)隔离级别;2)用到的索引。不同的隔离级别,不同的索引都会影响加锁。 2.1 可提交读RC 主键/唯一键 二级索引 无索引 select 无 无 无 insert 行锁 行锁 行锁 select...for update/update/delete 行锁 有效行的行锁 全表锁聚簇索引 2.2 可重复读RR 主键/唯一键 二级索引 无索引 select 无 无 无 insert 行锁 行锁 行锁 select...for update/update/delete 行锁 有效行的行锁 +gap锁 全表锁聚簇索引 2.3 可序列化S 主键/唯一键 二级索引 无索引 select(快照读) S S S 其他(当前读) X X X   注意:无索引时,select...for

MySQL中一条SQL的加锁分析

依然范特西╮ 提交于 2019-11-26 16:26:55
MySQL中一条SQL的加锁分析 id主键 + RC id唯一索引 + RC id非唯一索引 + RC id无索引 + RC id主键 + RR id唯一索引 + RR id非唯一索引 + RR id无索引 + RR Serializable 一条复杂的SQL 死锁原理与分析 SQL1: select * from t1 where id = 10;(不加锁。因为MySQL是使用多版本并发控制的,读不加锁。) SQL2: delete from t1 where id = 10;(需根据多种情况进行分析) 假设t1表上有索引,执行计划一定会选择使用索引进行过滤 (索引扫描),根据以下组合,来进行分析。 组合一 : id列是主键,RC隔离级别 组合二 : id列是二级唯一索引,RC隔离级别 组合三 : id列是二级非唯一索引,RC隔离级别 组合四 : id列上没有索引,RC隔离级别 组合五 : id列是主键,RR隔离级别 组合六 : id列是二级唯一索引,RR隔离级别 组合七 : id列是二级非唯一索引,RR隔离级别 组合八 : id列上没有索引,RR隔离级别 组合九 : Serializable隔离级别 注:在前面八种组合下,也就是RC,RR隔离级别下,SQL1:select操作均不加锁,采用的是快照读,因此在下面的讨论中就忽略了,主要讨论SQL2:delete操作的加锁。 1.

MySQL加锁分析

馋奶兔 提交于 2019-11-26 16:26:38
参考: MySQL 加锁处理分析 。该文已经讲的很详尽了,也易懂,下面仅仅是个人做的总结。 一、 背景 1.1 隔离级别 1.2 加锁过程    逐条处理,逐条加锁。 1.3 两阶段锁2PL 1.4 gap锁   gap锁是间隙锁,即相邻两条有效记录间隙的锁(锁的是间隙),它是 针对insert的 ,用来解决幻读的发生。 它会阻塞insert,但不会阻塞delete/update等 (记录本来也不存在)。   RC与RR的重要区别就是幻读。所以RR才需要引入gap锁。 二、加锁组合分析   说加什么锁,首先要了解两个前提:1)隔离级别;2)用到的索引。不同的隔离级别,不同的索引都会影响加锁。 2.1 可提交读RC 主键/唯一键 二级索引 无索引 select 无 无 无 insert 行锁 行锁 行锁 select...for update/update/delete 行锁 有效行的行锁 全表锁聚簇索引 2.2 可重复读RR 主键/唯一键 二级索引 无索引 select 无 无 无 insert 行锁 行锁 行锁 select...for update/update/delete 行锁 有效行的行锁 +gap锁 全表锁聚簇索引 2.3 可序列化S 主键/唯一键 二级索引 无索引 select(快照读) S S S 其他(当前读) X X X   注意:无索引时,select..

设置mysql 事务锁超时时间 innodb_lock_wait_timeout

孤街浪徒 提交于 2019-11-26 13:26:31
Mysql数据库采用InnoDB模式,默认参数:innodb_lock_wait_timeout设置锁等待的时间是50s,一旦数据库锁超过这个时间就会报错。 mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout'; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | innodb_lock_wait_timeout | 50 | +--------------------------+-------+ 1 row in set (0.00 sec) 郑州不孕不育医院哪家好:http://jbk.39.net/yiyuanzaixian/zztjyy/ mysql> SET GLOBAL innodb_lock_wait_timeout=120; Query OK, 0 rows affected (0.00 sec) mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout'; +--------------------------+-------+ | Variable_name | Value | +-

【锁】MySQL和Oracle行锁比较

血红的双手。 提交于 2019-11-26 02:03:26
InnoDB INNODB表是索引组织的表,主键是聚集索引,非主键索引都包含主键信息。 INNODB默认是行锁。 INNODB行锁是通过给索引项加锁来实现的,即只有通过索引条件检索数据,InnoDB才使用行级锁,否则将使用表锁。 InnoDB行锁实现方式 InnoDB行锁是通过给索引上的索引项加锁来实现的,如果没有索引,InnoDB将通过隐藏的聚集索引来对记录加锁。InnoDB行锁分为3种情形。 Record lock: 对索引项加锁。 Gap lock: 对索引项之间的“间隙”、第一条记录前的“间隙”或最后一条记录后的“间隙”加锁。 Next-key lock: 前两种的组合,对记录及其前面的间隙加锁。 InnoDB这种行锁实现特点意味着:如果不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,实际效果跟表锁一样! 在实际应用中,要特别注意InnoDB行锁的这一特性,否则可能导致大量的锁冲突。 Oracle 在Oracle的每行数据上,都有一个标志位来表示该行数据是否被锁定。这样就大大减小了行级锁的维护开销,数据行上的锁标志一旦被置位,就表明该行数据被加X锁,Oracle在数据行上没有S锁。 许多对Oracle不太了解的技术人员可能会以为每一个TX锁代表一条被封锁的数据行,其实不然。TX的本义是Transaction(事务),当一个事 务第一次执行数据更改

MySQL锁会不会,你就差看一看

冷暖自知 提交于 2019-11-25 16:47:50
数据库锁知识 不少人在开发的时候,应该很少会注意到这些锁的问题,也很少会给程序加锁(除了库存这些对数量准确性要求极高的情况下),即使我们不会这些锁知识,我们的程序在一般情况下还是可以跑得好好的。因为这些锁数据库隐式帮我们加了,只会在某些特定的场景下才需要手动加锁。 对于UPDATE、DELETE、INSERT语句,InnoDB会自动给涉及数据集加排他锁(X) MyISAM在执行查询语句SELECT前,会自动给涉及的所有表加读锁,在执行增、删、改操作前,会自动给涉及的表加写锁,这个过程并不需要用户干预 表锁 首先,从锁的粒度,我们可以分成两大类: 表锁 :开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低 行锁:开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高 不同的存储引擎支持的锁粒度是不一样的==:InnoDB行锁和表锁都支持、MyISAM只支持表锁!InnoDB只有通过索引条件检索数据才使用行级锁==,否则,InnoDB使用表锁也就是说,InnoDB的行锁是基于索引的! 表锁下又分为两种模式: 表读锁(Table Read Lock)&& 表写锁(Table Write Lock) 从下图可以清晰看到,在表读锁和表写锁的环境下:读读不阻塞,读写阻塞,写写阻塞!读读不阻塞:当前用户在读数据,其他的用户也在读数据,不会加锁 读写阻塞