锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(如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;
获得锁,插入或更新操作完成
写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁。
当前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;
打开终端
当前sessoin读mylock表:
其他session读mylock表等待:select * from mylock;
当前session释放读锁:unlock tables;
获得锁读取mylock完成:
当前的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不适合做写为主表的引擎。因为写锁后,其他线程不能做任何操作,大量的更新会使查询很难得到锁,从而造成永远阻塞
从对数据操作的粒度分:
表锁
行锁