锁定义
锁是计算机协调多个进程或线程并发访问某个资源的机制。
在数据库系统中, 除了传统的计算机资源(如:CPU, RAM。I/O等)的争用外, 数据也是一种供多用户共享的资源。如何保证数据并发的访问和一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤重要,也更加复杂。
生活购物案例
打个比方,我们到淘宝上买个一件商品,商品库存只有一件, 这个时候,如果有另外的买家。那么如何解决是你买到还是别人买到的问题。 示例:
这里肯定要用到事务,我们先从库存中取出物品的数量,然后插入订单。付款后插入付款信息。然后更新商品数量,这个过程使用锁,可以对有限的资源进行保护,解决隔离和并发的矛盾。
锁的分类
对数据操作的类型分(读/写)
- 读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会相互影响
- 写锁(排他锁):当前写操作没有完成之前,它会阻隔其他写锁和读锁
对数据操作的粒度来分
- 表锁
- 行锁
三种常见的锁
表锁(偏读)
特点偏向 MyISAM 存储引擎,开销小,加锁块;无死锁;锁定粒度大,发生锁冲突的概率高,并发度最低。案例分析建立表 SQL
use big_data; create table mylock ( id int not null primary key auto_increment, name varchar(20) default '' ) engine myisam; insert into mylock(name) values('a'); insert into mylock(name) values('b'); insert into mylock(name) values('c'); insert into mylock(name) values('d'); insert into mylock(name) values('e'); select * from mylock;
加读锁
加写锁
案例结论
表锁分析
- 查询被锁定的表
show open tables;
- 如果分析表锁
通过检查 table_locks_waited 和 table_locks_immediate 状态变量来分析系统上的表锁定;
SQL: show status like 'table%';
例子:这里有两个状态变量记录 mysql 内部表级锁定的情况,两个变量说明如下:
- Table_locks_immediate:产生表级锁定的次数,表示可以理解获取锁的查询次数,每次立即获取锁值增加
- Table_locks_waited: 出阿信啊标记锁定争用而发生的等待的次数(不能理解获取锁的次数,每等待一次锁值加1),此值则说明存在着比较严重的表级争用的情况。
此外, Myisam 的读写锁调度是写优先的, 这就是myisam 不适合做写为主表的引擎,因为写锁后, 其他线程不能做任何操作, 大量的更新会使查询很难得到锁,从而造成永远阻塞。
页锁
开销和加锁时间介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般。