百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>数据库> 对于mysql锁机制道理的细致解说(一)
分享文章到:

对于mysql锁机制道理的细致解说(一)

发布时间:09/01 来源:未知 浏览: 关键词:
锁是盘算机调和多个进程或线程并发拜访某一资源的机制。在数据库中,除传统的盘算资源(如CPU、RAM、IO等)的争用之外,数据也是一种供很多会员同享的资源。怎样保障数据并发拜访的一致性、有效性是所有数据库必需解决的一个题目,锁冲突也是影 是盘算机调和多个进程或线程并发拜访某一资源的机制。在数据库中,除传统的 盘算资源(如CPU、RAM、I/O等)的争用之外,数据也是一种供很多会员同享的资源。怎样保障数据并发拜访的一致性、有效性是所有数据库必需解决的一 个题目,锁冲突也是影响数据库并发拜访机能的一个重要因素。从这个角度来说,锁对数据库而言显得尤为重要,也更加复杂。本章我们着重计议MySQL锁机制 的特色,常见的锁题目,以及解决MySQL锁题目的一些办法或倡议。
Mysql用到了许多这种锁机制,比方行锁,表锁等,读锁,写锁等,都是在做操纵以前先上锁。这些锁统称为乐观锁(Pessimistic Lock)。

MySQL锁概述

相对其他数据库而言,MySQL的锁机制比拼简略,其最 显著的特色是不一样的存储引擎支撑不一样的锁机制。比方,MyISAMMEMORY存储引擎采纳的是表级锁(table-level locking);BDB存储引擎采纳的是页面锁(page-level locking),但也支撑表级锁;InnoDB存储引擎既支撑行级锁(row-level locking),也支撑表级锁,但默许状况下是采纳行级锁。
表级锁:开销小,加锁快;不会涌现死锁;锁定粒度大,产生锁冲突的概率最高,并发度最低。
行级锁:开销大,加锁慢;会涌现死锁;锁定粒度最小,产生锁冲突的概率最低,并发度也最高。
页面锁:开销和加锁工夫界于表锁和行锁之间;会涌现死锁;锁定粒度界于表锁和行锁之间,并发度个别
从上述特色可见,很难笼统地说哪种锁更好,只能就概括利用的特色来说哪种锁更合适!仅从锁的角度 来说:表级锁更适合于以查询为主,只要少量按索引前提更新数据的利用,如Web利用;而行级锁则更适合于有批量按索引前提并发更新少量不一样数据,同时又有 并发查询的利用,如一些在线事务处置(OLTP)系统。

MyISAM表锁

MySQL的表级锁有两种模式:表同享读锁(Table Read Lock)和表独有写锁(Table Write Lock)。
对MyISAM表的读操纵,不会阻塞其他会员对统一表的读要求,但会阻塞对统一表的写要求;对 MyISAM表的写操纵,则会阻塞其他会员对统一表的读和写操纵;MyISAM表的读操纵与写操纵之间,以及写操纵之间是串行的!依据如表20-2所示的 例子可以晓得,当一个线程获得对一个表的写锁后,只要持有锁的线程可以对表进行更新操纵。其他线程的读、写操纵都会期待,直到锁被开释为止。

MyISAM存储引擎的写锁阻塞读例子:
当一个线程获得对一个表的写锁后,只要持有锁的线程可以对表进行更新操纵。其他线程的读、写操纵都会期待,直到锁被开释为止。

给MyISAM表显示加锁,个别是为了在一定程度模拟事务操纵,实现对某一工夫点多个表的一致性读取。例如, 有一个订单表orders,其中记载有各订单的总金额total,同时还有一个订单明细表order_detail,其中记载有各订单每一产品的金额小计 subtotal,假如我们需要检查这两个表的金额合计可否符合,可能就需要施行如下两条SQL:

Select sum(total) from orders;
Select sum(subtotal) from order_detail;

这时,要是不先给两个表加锁,就可能发生差错的效果,由于首先条语句施行历程中,order_detail表可能已经产生了转变。因而,准确的办法应当是:

Lock tables orders read local, order_detail read local;
Select sum(total) from orders;
Select sum(subtotal) from order_detail;
Unlock tables;

要特殊注明下列两点内容:
1、上面的例子在LOCK TABLES时加了“local”选项,其作用就是在知足MyISAM表并发插入前提的状况下,允许其他会员在表尾并发插入记载,有关MyISAM表的并发插入题目,在背面还会进一步介绍。
2、在用LOCK TABLES给表显式加表锁时,必需同时取得所有波及到表的锁,而且MySQL不支撑锁升级。也就是说,在施行LOCK TABLES后,只能拜访显式加锁的这些表,不克不及拜访未加锁的表;同时,要是加的是读锁,那么只能施行查询操纵,而不克不及施行更新操纵。其实,在主动加锁的 状况下也根本如此,MyISAM总是一次获得SQL语句所需要的全部锁。这也正是MyISAM表不会涌现死锁(Deadlock Free)的缘由。

当运用LOCK TABLES时,不仅需要一次锁定用到的所有表,并且,统一个表在SQL语句中涌现多少次,就要通过与SQL语句中雷同的又名锁定多少次,不然也会出错!举例注明如下。

(1)对actor表获得读锁:

mysql> lock table actor read; 
Query OK, 0 rows affected (0.00 sec)

(2)但是通过又名拜访会提醒差错:

mysql> select a.first_name,a.last_name,b.first_name,b.last_name 
from actor a,actor b 
where a.first_name = b.first_name and a.first_name = 'Lisa' and a.last_name = 'Tom' and a.last_name <> b.last_name;
ERROR 1100 (HY000): Table ‘a’ was not locked with LOCK TABLES

(3)需要对又名离别锁定:

mysql> lock table actor as a read,actor as b read;
Query OK, 0 rows affected (0.00 sec)

(4)按照又名的查询可以准确施行:

mysql> select a.first_name,a.last_name,b.first_name,b.last_name 
from actor a,actor b where a.first_name = b.first_name 
and a.first_name = 'Lisa' and a.last_name = 'Tom' and a.last_name <> b.last_name;
+————+———–+————+———–+ 
| first_name | last_name | first_name | last_name | 
+————+———–+————+———–+ 
| Lisa | Tom | LISA | MONROE | 
+————+———–+————+———–+ 
1 row in set (0.00 sec)

查询表级锁争用状况

可以通过检查table_locks_waited和table_locks_immediate状态变量来剖析系统上的表锁定争夺:

mysql> show status like 'table%';
1Variable_name | Value 
Table_locks_immediate | 2979 
Table_locks_waited | 0 
2 rows in set (0.00 sec))

要是Table_locks_waited的值比拼高,则注明存在着较重大的表级锁争用状况。

并发插入(Concurrent Inserts)

上文提到过MyISAM表的读和写是串行的,但这是就总体而言的。在一定前提下,MyISAM表也支撑查询和插入操纵的并发进行。
MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值离别可认为0、1或2。

1、当concurrent_insert设定为0时,不允许并发插入。

2、当concurrent_insert设定为1时,要是MyISAM表中没有空泛(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记载。这也是MySQL的默许设定。

3、当concurrent_insert设定为2时,不管MyISAM表中有没有空泛,都允许在表尾并发插入记载。

鄙人面的例子中,session_1获得了一个表的READ LOCAL锁,该线程可以对表进行查询操纵,但不克不及对表进行更新操纵;其他的线程(session_2),虽然不克不及对表进行删除和更新操纵,但却可以对该表进行并发插入操纵,这里假如该表中间不存在空泛。

上文提到过MyISAM表的读和写是串行的,但这是就总体而言的。在一定前提下,MyISAM表也支撑查询和插入操纵的并发进行。
MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值离别可认为0、1或2。

当concurrent_insert设定为0时,不允许并发插入。当concurrent_insert设定为1时,要是MyISAM表中没有空泛(即表的中间没有被删除的行),MyISAM允许在一个进程读表的同时,另一个进程从表尾插入记载。这也是MySQL的默许设定。当concurrent_insert设定为2时,不管MyISAM表中有没有空泛,都允许在表尾并发插入记载。

鄙人面的例子中,session_1获得了一个表的READ LOCAL锁,该线程可以对表进行查询操纵,但不克不及对表进行更新操纵;其他的线程(session_2),虽然不克不及对表进行删除和更新操纵,但却可以对该表进行并发插入操纵,这里假如该表中间不存在空泛。

MyISAM存储引擎的读写(INSERT)并发例子:

别的,MySQL也供给了一种折中的方法来调理读写冲突,即给系统参数max_write_lock_count设定一个合适的值,当一个表的读锁达到这个值后,MySQL就临时将写要求的优先级落低,给读进程一定获得锁的时机。

上面已经计议了写优先调度机制带来的题目和解决方法。这 里还要强调一点:一些需要长工夫运转的查询操纵,也会使写进程“饿死”!因而,利用中应尽量以免涌现长工夫运转的查询操纵,不要总想用一条SELECT语 句来解决题目,由于这种看似奇妙的SQL语句,往往比拼复杂,施行工夫较长,在可能的状况下可以通过运用中间表等措施对SQL语句做一定的“分解”,使每 一步查询都能在较短工夫完成,从而减少锁冲突。要是复杂查询不成以免,应尽量安排在数据库余暇时段施行,比方一些按期统计可以安排在夜间施行。

后续会为大家解说InnoDB锁。

相理解更多相干题目请拜访百分百源码网:Mysql视频教程

以上就是对于mysql锁机制道理的细致解说(一)的细致内容,更多请关注 百分百源码网 其它相干文章!

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有152人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板