欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

关于MySQL两种引擎下的锁介绍

程序员文章站 2022-03-02 21:50:01
介绍mysql两种引擎下的锁。 1.两种引擎的锁介绍 myisam的锁 myisam存储引擎采用的是表级锁, innodb的锁 innodb既支持表级锁,有支持行锁,默认情况下是行锁。...

介绍mysql两种引擎下的锁。

1.两种引擎的锁介绍

myisam的锁 myisam存储引擎采用的是表级锁,
innodb的锁 innodb既支持表级锁,有支持行锁,默认情况下是行锁。

innodb还支持事务特性

2.具体锁的特性

表级锁 开销小,加锁快,不会出现死锁,锁定粒度大,发生锁的冲突概率高,开发度最低,并发度低
行级锁 开销大,加锁慢,会出现死锁,锁定粒度小,发生锁的冲突概率低,开发度高,并发度一般

总结:两种锁各有优缺点。表级锁更适合用于查询为主,只有少量按索引更新数据的应用,例如web应用。而行级锁则更适合有大量按照索引条件并发更新少量不同数据,同时又有并发处理查询的引用。如一些在线事务处理的。

3.myisam表锁介绍

3.1 锁分类

myisam的表级锁有两种模式:表共享读锁、表独占锁,他们的兼容性如下表格所示

当前锁模式/请求模式 none 读锁 写锁
读锁(当前模式) 兼容 兼容 不兼容
写锁(当前模式) 兼容 不兼容 不兼容

从上可以看出,myisam的表读操作不会阻塞其他用户对同一表的读操作,但是会阻塞对同一表的写操作;而写操作则会阻塞其他用户对同一表的读和写操作。写操作和读操作之间,以及写操作之间是串行的。

3.2 如何加表锁

1.>:默认情况下myisam在执行select语句(查询)时,自动会加表读锁;而在执行update,delete,insert语句时,会自动给设计到的表加上写锁,这个过程用户完全不用做任何干预。

2>:显示加表锁。例如在执行sql语句前 lock table user write (给user表加表写锁),用处一般是为了模拟事务存在,例如有一个订单表,还有一个订单明细表,为了检查这两个表的金额是否相符,那么就需要执行如下

select sum(total) from orders;

select sum(subtotal) from order_detail;

这两个表如果不给其加上锁,有可能某一个表会添加修改数据,造成数据读取不一致。所以需要在执行这两句前执行

lock tables orders read local,order_detail read local; //这里的local表示允许在表尾并发插入

.....

unlock tables; //解锁

3.3 myisam加锁的注意事项

1>:显示加锁,如上文中如果加了某一种锁,那么只能执行相应的操作,加了读锁,只能读取select,不能update,delete,insert.反之,隐式锁同理。

2>: 执行了local table 后,当前会话只能访问当前加锁的表,不能访问其他表,否则报错。

3>:对当前的表显示加锁后,如果当前表用了别名,用了多次也会报错,隐式不会有这样的情况。如下:

lock table actor read;

selelct a.name b.name from actor a, actor b where a.name = b.name and a.name="vison"; //报错

需要修改加锁条件为:lock table actor as a read,actor as b read;

4>:myisam总是一次获取sql语句所需要的全部锁,这也是myisam不会出现死锁的原因。

3.4 myisam 并发插入

总体而言,myisam表的读和写是串行的,但是在一定条件下也是支持查询和插入并发进行。这个存储引擎又给系统变量concurrent_insert专门用于控制并发插入的行为。

concurrent_insert的值 并发插入可行性
concurrent_insert=0 不允许并发插入
concurrent_insert=1 如果myisam表没有空洞(即表中间没有删除行),则允许插入在表尾,(通过optimize table 可以去除空洞,自行百度)
concurrent_insert=2 无论有没有空洞,都允许在表尾并发插入数据

3.5 myisam锁的调度

问题:如果一个读请求和一个写请求同时到达,那么优先让哪一个进程的请求获取到锁呢?

答案:写进程获取,就算是读请求先到达进入排队,也会先让写请求插队,这是由于mysql默认认为写请求比读请求重要,这也是myisam表不太适合有大量更新操作和查询操作的原因,大量的更新操作会让查询很难获取到锁。不过可以通过启动参数调节

set low_priority_updates = 1 表示降低更新优先级,当然还有 insert,update,delete 。当前也可以设置max_write_lock_count设置一个合适的值,当表的写锁到达一个值后,就将写锁优先级降低。