超快驾驭innodb锁概念,InnoDB引擎的行锁和表锁

1 .获取innodb行锁争用情况

innodb的锁分两类:lock和latch。

InnoDB引擎的行锁和表锁

计算机程序锁

  1.1 通过检查innodb_row_lock状态变量来分析系统上的行锁的争夺情况

  其中latch主要是保证并发线程操作临界资源的正确性,要求时间非常短,所以没有死锁检测机制。latch包括mutex(互斥量)和rwlock(读写锁)。

mysql常用引擎有MYISAM和InnoDB,而InnoDB是mysql默认的引擎。
MYISAM支持表锁但不支持行锁,而InnoDB支持行锁和表锁。


SHOW STATUS LIKE 'innodb_row_lock%'

  而lock是面向事务,操作(表、页、行)等对象,用来管理共享资源的并发访问,是有死锁检测机制的。

在mysql 的 InnoDB引擎支持行锁,与Oracle不同,mysql的行锁是通过索引加载的,即是行锁是加在索引响应的行上的,要是对应的SQL语句没有走索引,则会全表扫描,行锁则无法实现,取而代之的是表锁。

 

图片 1

现在我们要着重讲的是innodb的lock锁,下面我们先来介绍几个概念。

行锁必须有索引才能实现,否则会自动锁全表,那么就不是行锁了。
两个事务不能锁同一个索引

  • 控制对共享资源进行并发访问
  • 保护数据的完整性和一致性

    通过innodb_row_lock_waits 和 innodb_row_lock_avg 的值来判断行锁争用情况,值高意味着争用比较严重。

行锁:innodb实现了多粒度锁,作用对象为表则为表锁,作用对象为行(Record)则为行锁。其中行锁包括共享行锁和排他行锁。

insert ,delete , update在事务中都会自动默认加上排它锁。

 图片 2

  1.2 通过检查 innodb monitors来观察发生锁冲突的表,数据行等,并分析锁争用的原因

共享行锁(S):允许事务读取一行数据。

图片 3

 

-- 查看分析
SHOW ENGINE INNODB STATUS;

排他行锁(X):允许事务删除或更新一行数据。

image.png

图片 4.png)

  status内容中会详细说明当前锁等待的信息,包括表名,锁类型,锁定记录的情况等,以便进行进一步的分析和问题的确定。以后在详细分析

意向锁:数据库需要对细粒度的对象上锁,需要首先给粗粒度的对象上锁。在粗粒度对象上上的锁成为意向锁。innodb的意向锁包括共享意向表锁和排他意向表锁。

InnoDB实现了两种类型的行锁。
共享锁(S):允许一个事务去读一行,阻止其他事务获得相同的数据集的排他锁。
排他锁(X):允许获得排他锁的事务更新数据,但是组织其他事务获得相同数据集的共享锁和排他锁。

lock  主要是事务,数据库逻辑内容,事务过程

图片 5

共享意向表锁(IS):S锁对应IS锁

可以这么理解:
共享锁就是我读的时候,你可以读,但是不能写。排他锁就是我写的时候,你不能读也不能写。其实就是MyISAM的读锁和写锁,但是针对的对象不同了而已。

latch/mutex 内存底层锁;

2. innodb 行锁模式及加锁方法

排他意向表锁(IX):X锁对应IS锁

除此之外InnoDB还有两个表锁:
意向共享锁(IS):表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁
意向排他锁(IX):类似上面,表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。

 

两种锁模式(类型)共享锁, 排它锁。
  共享锁(S):允许其它事务读取该行数据,阻止其它事务获取排他锁去更新。
  排它锁(x): 阻止其它事务读取或更新。
为了允许行锁和表锁共存,实现多粒度锁机制,innodb内部使用意向锁,这二种意向锁都是表锁。
  意向共享锁(IS): 当前事务打算给数据行加S锁,必须先取得该表的IS锁。
  意向排它锁(IX): 当前事务打算给数据行加x锁,必须先取得该表的IX锁。

锁兼容:兼容是指在同一对象上允许同种或不同种锁同时存在。 

注意:
当一个事务请求的锁模式与当前的锁兼容,InnoDB就将请求的锁授予该事务;反之如果请求不兼容,则该事务就等待锁释放。

更新丢失

下图是innodb 行锁模式兼容性列表

lock锁的分类

意向锁是InnoDB自动加的,不需要用户干预。
对于insert、update、delete,InnoDB会自动给涉及的数据加排他锁(X);对于一般的Select语句,InnoDB不会加任何锁,事务可以通过以下语句给显示加共享锁或排他锁。


图片 6

  innodb实现了行级锁,包括行级共享锁(S)及行级排它锁(X),其中S和S是兼容的,其它都是不兼容的。所谓兼容是指对同一记录(row)锁的兼容性情况。innodb通过意向锁实现多粒度锁定。对innodb而言只有表意向共享锁(IS)和表意向排他锁(IX)。在给表加行锁前,需要先对该表加意向锁。因为意向锁是表级别的,而innodb的其它锁是行级别的,所以如果不是全表扫,意向锁是不会对堵塞其它请求的。(小编这里特地做了一个实验,发现select * from t1 where id=5 for update,此时id上面没有索引,走的是全表扫描,确实堵塞了其它任何请求。但给id加上索引,没有走全表时,就没有堵塞其它请求了。)各锁之间的兼容情况请看下图:

共享锁:select * from table_name where .....lock in share mode
排他锁:select * from table_name where .....for update

原因:

  通过上图可以总结出来: S与IS锁在事务与事务之间是兼容的。 ix锁与(ix锁或is锁)在事务与事务之间是兼容的。 is锁与(IX,S,IS锁)是兼容的。X锁与其它锁是互斥的。
  当事务将要获取的锁与其它事务的锁兼容时,就会授予该事务锁,否则该事务就要等待其它事务锁的释放。
  对于update,delete,insert语句,innodb会自动给涉及的数据集加X锁(对于delete,update会先加S锁再升级为X锁)。
  对于普通的select语句innodb会加S锁。

  图片 7

意向锁的作用:
意向锁是在添加行锁之前添加。当再向一个表添加表级X锁的时候:
如果没有意向锁的话,则需要遍历所有整个表判断是否有行锁的存在,以免发生冲突。
如果有了意向锁,只需要判断该意向锁与即将添加的表级锁是否兼容即可。因为意向锁的存在代表了,有行级锁的存在或者即将有行级锁的存在。因而无需遍历整个表,即可获取结果。

B的更改还没有提交时,A已经再次修改了数据。

3. 语句级加锁

简记:含I的锁与含I的锁是相互兼容的

Thus, intention locks do not block anything except full table requests (for example, LOCK TABLES ... WRITE). The main purpose of IX and IS locks is to show that someone is locking a row, or going to lock a row in the table.

此时A使用原来的元数据作为基础更新后,B的更新便会丢失;

  lock in share mode(语句集上加IS锁)
    在select 语句最后加上lock in share mode相当于手动加上共享锁。确保当前没有人对该记录进行update或delete操作。
  for update(语句集上加IX锁)
    select for update是对锁定行记录后,需要进行更新操作的应用。
        (未完)

   不含I的锁,含S的与含S的兼容与含X的不兼容

引用官方的话来说就是:意向锁只会阻塞全表锁,不会阻塞没有交集的行锁。目的是为了提高读写性能。

图片 8.png)

        不含I的锁,含X的与任何锁都不兼容

图片 9

如何查看锁

 

1、通过show engine innodb statusG;

解决办法:

2、直接查询试图 innodb_trx,innodb_locks,innodb_lock_waits;

在修改数据上加写锁,当有锁时,A会等B更新提交完,才可以继续在B的基础上继续更新;

关于读请求的锁

图片 10.png)

读请求可以分为两类:一致性锁定读和一致性非锁定读。

 图片 11

一致性锁定读是指读取数据的时候需要给表上加锁,有两种锁定形式:

 

  select * from t1 for update;(加的是X锁)

 

  select * from t1 in share mode;(加的是S锁)

事务锁粒度

而一致性非锁定读是指读取数据的时候不给表加锁,利用MVCC(multi version concurrency control)特性当读取数据时如果碰到对象已经上了X锁就直接读取镜像数据。又因为事务隔离级别的不同,在不同事务隔离级别下读取的镜像也会不同。


自增长键的锁

 

一般情况下innodb的主键都会设为自增长,但是当并发往表里插入数据的时候,数据入库的效率会因为自增长的设置而受到影响。5.1.22之前的版本是通过auto_inc locking(锁不是在完成事务后释放而是在完成自增长值插入的SQL后释放)来实现自增长的。5.1.22及之后的版本,innodb提供了一种轻量级互斥量的自增长实现机制,并提供了inodb_atuoinc_lock_mode来控制自增长的模式。该参数的默认值为1.修改为2时效率最高,但是会造成自增长的值不连续并且基于语句级的主从复制也会出现数据不一致的问题。

行锁: innodb ,oracle

外键锁问题

页锁:sql server

生产数据库上是不建议使用外键的。为什么呢。因为对外键的插入和更新会检索父表。而对父表的检索使用的是一致性锁定读(select ... from ...in share mode),这样会堵塞其它事务对父表的请求。

表锁:Myisam ,memory

锁的算法

 

锁有三种算法:

获取innodb行锁争用情况

  Record Lock:单个记录上的锁

 

  Gap Lock:间隙锁(锁定范围但不包含记录本身)

mysql> show status like '%innodb_row_lock%';
 ------------------------------- ------- 
| Variable_name                 | Value |
 ------------------------------- ------- 
| Innodb_row_lock_current_waits | 0     |
| Innodb_row_lock_time          | 0     |
| Innodb_row_lock_time_avg      | 0     |
| Innodb_row_lock_time_max      | 0     |
| Innodb_row_lock_waits         | 0     |
 ------------------------------- ------- 
5 rows in set (0.00 sec)

  Next-Key Lock:锁定一个范围并且包括记录本身,Innodb对于行的查询都采用这种算法(为了解决幻读)。但查询的索引含有唯一属性时,innodb存储引擎会对next-key lock进行优化,将其降级为Record Lock。即仅锁住索引本身,而不是范围。若是辅助索引则会分别对当前辅助索引及聚集索引加锁定。对聚集索引采用Record Lock锁定,而辅助索引则使用Next-Key Lock锁定(需要注意的是innodb会对辅助索引的下一个键值上加上gap lock)

如果发现锁争用比较严重,如innodb_row_lock_waits 和 innodb_row_lock_time_avg的值比较高,

阻塞

还可以通过设置innodb monitor 来进一步观察发生锁冲突的表,数据行等,并分析锁争用的原因:

给一个对象加锁会阻塞其它对象对它的请求,innodb通过设置innodb_lock_wait_timeout来控制等待时间,并通过设置innodb_rollback_on_timeout来设置是否等待超时对事务进行回滚,默认不回滚,超过等待时间则抛出异常,由用户判断是该rollback还是commit。

 

死锁

 

死锁是指两个或两个以上的事务在执行过程中,因争夺锁资源而造成的一种相互等待的现象。死锁出现的概率是非常低的。innodb内置有死锁检查机制。当出现死锁时会自动回滚占用undo资源少的事务。

innodb锁模式与粒度

锁升级


很多数据库如:SQL server就有锁升级的想象,但是innodb并没有锁升级。这是因为innodb根据事务访问的每个页对锁进行管理,采用位图方式,因此不管一个事务锁住页中的一行还是多个记录,其开销通常都是一样的。

 

锁的问题

四种基本锁模式

使用锁可能会出现三类问题:

  • 共享锁(S)-读锁-行锁
  • 排他锁(X)-写锁-行锁
  • 意向共享锁(IS)-表级 :事务想要获得一张表中某几行的共享锁
  • 意向排他锁(IX)-表级:事务想要获得一张表中某几行的排他锁

脏读:读到未提交的数据(Read-ncommitted隔离级别);

 

不可重复读:(Read-committed);

意向锁,简单来说就是:

丢失更新:避免丢失更新的方式就是给select ... from ... 加上 for update;

如需要对页上的记录R进行X锁,那么分别需要对该记录所在的数据库,表,页,上意向锁IX,最后对记录R上X锁。

锁的常见的误区

若其中任何一个部分导致等待,那么该操作需要等待粗粒度锁的完成。

误区一:select col1,col2 from table1 where col1='xxx' 或select count(*) from  table1;会锁表;

 

事实上这样的select语句是不会对访问的资源加锁的。因为这样的查询会使用一致性非锁定读,它访问的是资源的镜像(此处用到的技术是mvcc即multi version concurrency control),所以不会堵塞其它事务也不会被其它事务堵塞(感兴趣的同学可以通过实验验证,不清楚实验方法的话可以私信我)。当然这只是一般的select语句。如果是如下这种格式的语句仍然会对访问的资源加锁:

innodb支持意向锁设计比较简练,其意向锁即为表级别的锁。设计目的主要是为了在一个事务中揭示下一行将被请求的锁类型。

select col1,col2 from table1 for update;(加X锁)

 

select col1,col2 from table1 lock in share mode;(加S锁)

意向锁:

    关于什么是共享锁(S)什么是互斥锁(X),上面已经做了介绍。我们需要注意的是S锁和S锁是兼容的,S锁和X锁、X锁和X锁是不兼容的。这里说的兼容指的是不同事务对同一行(row)资源的访问的兼容性。显式加锁的select请求,会堵塞其它资源对该表的意向锁请求,从而堵塞其它请求。所以一般情况下,如无特殊需求,是不允许应用对select语句显示加锁的。

  • 意向锁总是自动先加,并且意向锁自动加自动释放
  • 意向锁提示数据库这个session将要在接下来将要施加何种锁
  • 意向锁和X/S 锁级别不同,除了阻塞全表级别的X/S锁外其他任何锁 

误区二:update table1 set col1='xxx' where col2='xxx'不走索引对数据库的性能没有多大影响;

自动施加,自动释放,

当使用update语句时,首先该语句会对它所访问的表加意向排它锁(IX),如果update语句走了索引,那么它会使用行锁(X) ,只锁定访问的记录及间隙(想了解更多可以百度MySQL锁的算法)。而如果它没有走索引,就会进行全表扫,这时会给整个表加上排他锁(X)。这是这句SQL就会堵塞所有会对该表加意向锁(意向读及意向写)请求,从而堵塞其它请求。

 

误区三:自增长键会在整个事务过程中,锁住自增长值;

 

现在我们数据库中的表的主键都是设为自增长的。很多同事认为,这样会不会非常影响数据库的插入效率。事实上使用自增长值确实会影响数据入库的效率,当时mysql 5.1.22版本后,对数据库的自增长设计做了很大的优化,性能已经得到了很大的提升。在5.1.22 之前的版本,使用的是auto_inc locking来生成自增长主键。它并不是在整个事务过程中锁住自增长资源而是在要生产主键的SQL执行完后就释放资源。这就是我们为什么会碰到,事务回滚后,自增长值确仍旧增大的原因。5.1.22及之后,使用了轻量级互斥量(mutex)来实现自增长,并通过inodb_atuoinc_lock_mode来控制自增长的模式。数据库默认改参数值为1,一般情况下都是用mutex来控制自增长,只有当bulk inserts的时候才会使用auto_inc locking模式。

innodb锁模式互斥

误区四:使用外键加强约束,不会影响性能;

图片 12.png)

很多同事在设计表结构的时候喜欢使用外键,这里会给大家说明,为什么不建议大家使用外键。

图片 13

如果使用外键,那么当子表需要更新或插入数据的时候会去检索父表。问题就出现在,检索父表的使用并不是使用的是一致性非锁定读,而是使用的一致性锁定读。

 

内部检索会是下面的格式:select * from parent where ... lock in share mode;这样的检索就会堵塞同时访问该父表的其它事务的请求,从而影响性能。

数据库加锁操作

 

一般的select语句不加任何锁,也不会被任何事物锁阻塞

读的隔离性由MVCC确保

 

undo log 用来帮助事务回滚及MVCC(多版本并发控制 ,即select时可以使用行数据的快照,而不用等待锁资源)

 

S锁

  手动:select * from tb_test lock in share mode;

  自动:insert前

 

X锁

   手动:

select *  from tb_test   for update;

   自动:update,delete 前

 

线上环境中:

图片 14.png)

图片 15

 

锁等待时间:innodb_lock_wait_timeout

 

mysql>show global variables like "%wait%"

 

innodb 行锁


 

通过索引项加锁实现

  • 只有条件走索引才能实现行级锁                    a)
  • 索引上有重复值,可能锁住多个记录              b)
  • 查询有多个索引可以走,可以对不同索引加锁   c)
  • 是否对索引加锁实际上取决于Mysql执行计划

 

自增主键做条件更新,性能做好;

 

通过索引项加锁实现的例子:

a) 只有,有条件走索引才能实现行级锁

 

mysql> show create table t2G;
*************************** 1. row ***************************
       Table: t2
Create Table: CREATE TABLE `t2` (
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1

mysql> select * from t2;
 ------ ------ 
| a    | b    |
 ------ ------ 
|    1 |    2 |
|    1 |    3 |
 ------ ------ 

此时A连接 在b =2 时加 写锁;
mysql> select * from t2 where b =2 for update;
 ------ ------ 
| a    | b    |
 ------ ------ 
|    1 |    2 |
 ------ ------ 
而此时再B连接中再对b=3,加写锁时,失败;
mysql> select * from t2 where b=3 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

说明,表中没有索引时,innodb将对整个表加锁,而不能体现行锁的特性;

 

 

 b)  索引上有重复值,可能锁住多个记录 

 

mysql> show create table t2G;
*************************** 1. row ***************************
       Table: t2
Create Table: CREATE TABLE `t2` (
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL,
  KEY `a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> select * from t2;
 ------ ------ 
| a    | b    |
 ------ ------ 
|    1 |    2 |
|    1 |    3 |
|    2 |    9 |
 ------ ------ 

在A连接中,在a=1,b=2处加一个写锁;实际上 是在a=1这个索引上加的锁
mysql> select * from t2 where a=1 and b=2 for update;
 ------ ------ 
| a    | b    |
 ------ ------ 
|    1 |    2 |
 ------ ------ 
1 row in set (0.00 sec)

在B连接中,在a=1 and b=3处加写锁失败,因都是a=1这个索引,而A中已经对a=1这个索引的行加过了锁;
mysql> select * from t2 where a =1 and b=3 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

此时B连接是可以对 a=2 and b =9 这一行中,在a=2 这个索引上加锁的;
mysql> select * from t2 where a=2 and b =9 for update ;
 ------ ------ 
| a    | b    |
 ------ ------ 
|    2 |    9 |
 ------ ------ 

注意

行锁升级成表锁:

mysql> select * from t2 where  b =9 for update ;

这句对本意在b=9这行加索引,b又没有加索引,所以这是对整个表加锁;因为没有指定a =2,所以mysql找不到a这个索引的;

 

c)  查询有多个索引可以走,可以对不同索引加锁

 

mysql> show create table t2G;
*************************** 1. row ***************************
       Table: t2
Create Table: CREATE TABLE `t2` (
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL,
  KEY `a` (`a`),
  KEY `b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
mysql> select * from t2;
 ------ ------ 
| a    | b    |
 ------ ------ 
|    1 |    2 |
|    1 |    3 |
|    2 |    9 |
 ------ ------ 
在A连接中对 a=1 and b=2 加锁;
mysql> select * from t2 where a =1 and b =2  for update;
 ------ ------ 
| a    | b    |
 ------ ------ 
|    1 |    2 |
 ------ ------ 

此时B连接中对a =1 and b=3 ,也是可以加锁的;这是因为mysql 可以从a=1这个索引来加锁,也可以对b=3加锁;
所以就与上面b)中只能对a=1索引来加锁 区别开来;

mysql> select * from t2 where a =1 and b =3  for update;
 ------ ------ 
| a    | b    |
 ------ ------ 
|    1 |    3 |
 ------ ------ 

 

innodb的gap lock 间隙锁

 

gap lock消灭幻读

     innodb消灭幻读仅仅为了确保 statement模式replicate的主从一致性

 

小心gap lock

 

自增主键做条件更新,性能最好;

 

gap lock 间隙锁 解释:

 

mysql> select * from t2;
 ------ ------ 
| a    | b    |
 ------ ------ 
|   20 |    2 |
|   24 |    4 |
|   27 |    5 |
|   27 |    6 |
|   27 |    8 |
|   30 |    6 |
|   31 |    4 |
|   32 |    9 |
 ------ ------ 
8 rows in set (0.00 sec)

在A连接中给a=27 加锁(a 是有索引的)
mysql> select * from t2 where a=27 for update;
 ------ ------ 
| a    | b    |
 ------ ------ 
|   27 |    5 |
|   27 |    6 |
|   27 |    8 |
 ------ ------ 
3 rows in set (0.00 sec)

 

此时隔离等级是Repeatable  Read,标准的是可以出现幻读现象的,

即在B连接中 insert into t2 values(27,3),是可以插入成功的,而且B连接提交后,A连接是可以查看到增加的,27,3这一行的。

 

而innodb 通过间隙锁是的B连接中  insert into t2 values(27,3) 插入失败,来消灭幻读的出现。

但是这种方法是有局限的,它会将a=24--29(30-1)中间的任何数都锁住,所以才叫间隙锁;

 

B连接中则只能插入不在这个区间的数据;

 

锁升级


 

  • 由一句单独的sql语句在一个对象上持有的锁的数量超过了阈值,默认这个阈值为5000.值得注意的是,如果是不同对象,则不会发生锁升级。
  • 锁资源占用的内存超过了激活内存的40%时就会发生锁升级

 

innodb不存在锁升级的问题。因为其不是根据每个记录来产生行锁的,相反,其根据每个事务访问的每个页对锁进行管理的,采用的是位图的方式。因此不管一个事务锁住页中一个记录还是多个记录,其开销通常都是一致的。

 

简单说innodb根据页进行加锁,并采用位图方式,定位到行的,所需资源较小。

例子:

 图片 16

 

图片 17.png)

死锁


 图片 18

 

图片 19.png)

 

死锁数据库自动解决

     数据库挑选冲突事务中回滚代价较小的事务回滚

 

死锁预防

     单表死锁可以根据批量更新表的更新条件排序

     可能冲突的跨表事务尽量避免并发

     尽量缩短事务长度

 

排查死锁:

  • 了解触发死锁的sql所在事务的上下文
  • 根据上下文语句加锁的范围来分析存在争用的记录
  • 通常改善死锁的主要方法:

        --对同一表的操作根据加锁条件进行排序

        --拆分长事务

 

业务逻辑加锁


 

     业务流程中的悲观锁(开始的时候,在所有记录加锁,直到最后释放;而乐观锁开始不加锁,只是在最后提交中看提交有没有成功,没成功返回给应用程序)

 

     悲观锁开始就给所有记录加锁,一般等所有业务流程完成,才释放锁;因此会对并发性能有一定的影响;

 

如何缩短锁的时间?

1)开始的时候读取要修改的数据,amount(金额)

2)做业务流程

3)在update时,加锁且判断,现在的amount和开始的amount是否为一个值,如果是,说明这期间amount为改变,则更新;如果amount值改了,则不更新,交给业务来判断该怎么做。

 

这样仅是在update这个语句加锁,大大的缩短的锁的时间提高了并发性;

 

但是如果业务十分的繁忙,amount的值在不断改变,此时这个update 就不断的失败,整个事务就不断的失败,反而影响了 性能。那么该如何做呢?

 

在开始的时候不读取数据,等到要提交的时候读取并加锁提交;

 

 总结


 

  •  更新丢失
  •  innodb意向锁:
    • 表锁
    • 自动施加、自动释放
    • 为了揭示事务下一行将被请求的锁类型
  •  S锁:in share mode

  •  X锁:for update
  •  innodb行锁特点:
    • 只有条件走索引才能实现行锁
    • 索引上有重复值可能锁住多个记录
    • 查询有多个索引可以走,可以对不同索引加锁
  •  gap lock:间隙锁,消灭幻读

  •  死锁解决:数据库挑回滚代价较小的事务回滚;
  •  死锁预防:
    • 单表,更新条件排序
    • 避免跨表事务,缩短事务长度
  •  锁升级:

    • 单独sql语句在单个对象的锁数量超过阙值
    • 锁资源占用的内存超过了激活内存的40%;
  •  innodb根据页进行加锁,并采用位图方式,定位到行的,所需资源较小

 

本文由星彩网app下载发布于星彩彩票app下载,转载请注明出处:超快驾驭innodb锁概念,InnoDB引擎的行锁和表锁

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。