[mysql] 锁机制

前言

  在计算机的世界里锁(lock)是为了协调多个进程或者多个线程并发的访问同一资源而被创造出来的。而在咱们的mysql数据库中的锁也是为了解决并发访问同一资源的问题,下面我就来介绍下mysql中的锁的一些知识,若是有什么说的不对的地方,还但愿各位大神指正。mysql

 

 锁的种类

  在mysql数据库中,能够将锁分为3个种类: 表级锁 、 行级锁 、 页级锁 。sql

表级锁

定义:对整个表进行加锁处理,在你锁按期间,若是你是读锁,其余进程写操做没法对这张表进行操做。若是你是写锁,则其余进程没法对这张表进行操做。数据库

引擎: MyISAM , InnoDB 并发

优势: 加锁快 、 开销小 、 不会出现死锁 spa

缺点: 锁定面积大 、 发生冲突的几率高 、 并发度低 线程

表级锁模式

  •  表共享读锁 :当一个进程对一张表加了读锁,那么其余的进程也能够同时对这张表加读锁,可是不能加写锁。(即多个用户能够同时读取同一张表的数据)
  •  表独占写锁 :当一个进程对一张表加了写锁,那么其余任何进程都不能够加任何锁。

如何添加表级锁

lock tables table_name1 read local,table_name2 read local;
select * from table_name1;
select * from table_name2;
lock tables;

 

注意:code

  •  local 选项,做用是在知足MyISAM表并发插入条件的状况下,容许其余用户在表尾插入记录。
  • 在使用 lock tables 给表显示加锁后,你只能访问显示加锁的那几张表,不能访问未加锁的表。
  • 在使用 lock tables 给表显示加锁后,mysql是一次性加上你想加锁表的全部表的锁,这就保证了不会产生死锁。

MyISAM的锁

并发锁

MyISAM存储引擎中有一个系统变量 concurrent_insert ,这个变量能够控制并发插入的行为,容许的值为(0、一、2)。blog

  • 当 concurrent_insert=0 时,不容许并发插入。
  • 当 concurrent_insert=1 时,当一个进程在读一张表时,通知能够容许一个进程向该表中插入数据。(默认设置)
  • 当 concurrent_insert=2 时,不管MyISAM表中有没有空洞,都容许在表尾并发插入记录。

MyISAM锁调度

对于MyISAM的锁调度,咱们须要注意的是:索引

  • 写进程老是币读进程先得到锁,即便是读进程先到达等待队列,写进程后到达,以后mysql也会先调度写进程。

优势:由于MyISAM是共享读锁的,先执行写进程,可让读进程积累到必定程度,一块儿读取数据,能够增长并发度队列

缺点:若是写进程过多,那么会形成读进程一致没法执行,致使等待时间过长

能够经过如下几种方法解决读进程等待时间过长的问题:

  • 修改优先级
SET LOW_PRIORITY_UPDATES=1;
SET LOW_PRIORITY_INSERT=1;
SET LOW_PRIORITY_DELETE=1;
  • 设置 max_write_lock_count 参数,当一个表的读锁达到这个值后,MySQL变暂时将写请求的优先级下降,给读进程必定得到锁的机会。
set max_write_lock_count=10;

 

 

 行级锁

定义:对表中的一行进行加锁,其余进程还能够操做这张表的其余行。

引擎: InnoDB 

优势: 锁定面积小 、 发生冲突的几率低 、 并发度高 

缺点: 加锁慢 、 开销大 、 会发生死锁 

行级锁模式

  •  共享锁(s) :容许多个事务去读同一行,当某个事务对该行加共享行锁,则不容许其余事务去加排它锁。
  •  排它锁(X) :当某个事务给某一行加了排它锁,则不容许其余事务给该行加任何锁。
  •  意向共享锁(IS :在加共享锁前,首先须要在表上加该锁。
  •  意向排他锁(IX) :在加排它锁前,首先须要在表上加该锁。

注意如下几点:

  • 意向锁是InnoDB自动加的。
  • 对于 UPDATE 、 DELETE 、 INSERT 语句,InnoDB会自动加排它锁。
  • 对于 SELECT 语句,InnoDB不会加任何锁。能够经过如下语句给记录加共享锁:
select * from table_name where id = xxx lock in share mode;

 

InnoDB的锁

 行锁实现方式

  InnoDB行锁是经过索引上的索引项来实现的,只有经过索引条件检索数据,InnoDB才会使用行级锁,不然,InnoDB将使用表锁。

间隙锁

  当咱们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据的索引项加锁;对于键值在条件范围内但并不存在的记录,叫作“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制不是所谓的间隙锁(Next-Key锁)。

何时使用表级锁

  1. 更新的行数是表的大部分数据或整张表时
  2. 事务涉及多个表,比较复杂,极可能引发死锁,形成事务大量回滚。

在InnoDB下,使用表锁要注意如下几点:

  1. 可使用 lock tables 给InnoDB加表级锁,可是这个表级锁不是由InnoDB存储引擎管理的,而是上一层的MySQL Server管理,而且只有知足 autocommit=0 和 innodb_table_lock=1 时,InnoDB层才能知道MySQL加的表锁,MySQL Server才能感知InnoDB加的行锁,这种状况下,InnoDB才能自动识别涉及表级锁的死锁;不然,InnoDB将没法自动检测而且处理这种死锁。
  2. 在用 lock tables 对InnoDB锁时要注意,要将 autocommit 设置为0,不然MySQL不会给表加锁。

页级锁

定义:对表中某行和相邻行进行加锁。这种作法是对表级锁和行级锁的一中折中方案。

引擎:BDB

相关文章
相关标签/搜索