锁是计算机协调多个进程或线程并发访问某一资源的机制。
在数据库中,除传统的计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发
访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说
锁对数据库而言显得尤其重要,也更加复杂。
读锁(共享锁):针对同一-份数据,多个读操作可以同时进行而不会互相影响。
session01 |
session02 |
|
为mylock加读锁 |
session1为表mylock加读锁。 lock table mylock read; |
连接终端 |
读mylock |
当前可以读mylock表: select * from mylock; |
其他session也可以查mylock表: select * from mylock; |
读其他表 写其他表 |
当前session不能查询其他的表:select * from user; 当前session不能更新其他的表:insert into user(name,age) values(‘zzz‘,18); |
其他session可以查询其他未枷锁的表: select * from user; 其他的session可以写其他未加锁的表: insert into user(name,age) values(‘ylm‘,18); |
更新myclock |
当前session插入或更新mylock都会报错: insert into mylock(name) values(‘zs‘); |
其他session插入或更新mylock会一直等待获得锁(阻塞): insert into mylock(‘name‘)values(‘ls‘); |
释放锁 |
释放锁:unlock tables; |
获得锁,插入或更新操作完成 |
写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁。
session01 | session02 | |
添加写锁 | 当前session为mylock表添加写锁:lock table mylock write; | 打开终端 |
写mylock |
当前session为mylock插入数据:insert into mylock(name) values(‘sdf‘); |
其他session写mylock表等待(阻塞):insert into mylock(name) values(‘sdf‘); |
释放锁 |
当前session释放写锁:unlock tables; |
插入成功: |
添加写锁 |
当前session为mylock表添加写锁:lock table mylock write; |
打开终端 |
读mylock |
当前sessoin读mylock表: |
其他session读mylock表等待:select * from mylock; |
释放锁 |
当前session释放读锁:unlock tables; |
获得锁读取mylock完成: |
添加锁 | 当前session添加读锁:lock table mylock write; | 打开终端 |
读取其他的没有加锁的表 |
当前的session读取和插入其他未加索的表: select * from user; insert into user(name,age) values(‘fdsf‘,18); 不能读取和插入数据 |
当前的session读取和插入其他未加索的表: select * from user; insert into user(name,age) values(‘fdsf‘,18); 可以插入和读取数据
|
MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行增删改操作前,会自动给涉及的表加写锁
MySQL的表级锁有两种模式:
表共享读锁(Table Read L ock)
表独占写锁(Table Write Lock)
锁类型 | 是否可兼容 | 读锁 | 写锁 |
读锁 | 是 | 是 | 否 |
写锁 | 是 | 否 | 否 |
结论:
结合上表,所以对MyISAM表进行操作,会有以下情况:
1、对MyISAM表的读操作(加读锁),不会阻塞其他进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作。
2、对MyISAM表的写操作(加写锁),会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操
查看表的锁结构命令分析:
看看哪些表被加锁了
mysq|l>show open tables; ;
如何分析表锁定
可以通过检查table_ locks_ waited和table_ locks_ immediate状态变量来分析系统上的表锁定:
SQL: show status like ‘table%‘;
这里有两个状态变量记录MySQL内部表级锁定的情况,两个变量说明如下:
Table_ _locks_ immediate: 产生表级锁定的次数,表示可以立即获取锁的查询次数,每立即获取锁值加1 ;
Table_locks__waited:出现表级锁定争用而发生等待的次数(不能立即获取锁的次数,每等待一次锁值加1),此值高则说明存在着较严重的表级锁争用情况;
此外,Myisam的读写锁调度是写优先,这也是myisam不适合做写为主表的引擎。因为写锁后,其他线程不能做任何操作,大量的更新会使查询很难得到锁,从而造成永远阻塞
从对数据操作的粒度分:
表锁
行锁
原文:https://www.cnblogs.com/zzhAylm/p/14782963.html