锁的分类:
操作类型分类:
- 读锁(共享锁):对同一个数据,多个读操作可以同时进行,互不干扰。
- 写锁(互斥锁):如果当前写操作没有完毕,则无法进行其他的读写操作。
操作范围:
- 表锁:一次性对一张表加锁,如MyISAM存储引擎使用表锁,开销小,加锁快,无死锁;但是锁的范围大,容易发生锁冲突,并发度低。
- 行锁:一次性对一条数据加锁,如InnoDB存储引擎使用行锁,开销大,加锁慢,容易出现死锁;锁的范围较小,不易发生锁冲突,并发度高(很小概率发生高并发问题如:脏读,幻读,不可重复读,丢失更新等问题)。
- 页锁:
查看加锁的表:
show open tables;
加锁SQL:
lock table 表名 read/write ;
对t_tablelock表加读锁:
lock table t_tablelock read;
释放锁:
unlock tables;
总结:
1、如果会话1对A表加了read锁,则该会话可以对A表进行读操作,不能进行写操作;对其他表增删改查都不行。
2、会话1给A表加了锁,其他会话的操作:
- 可以对其他表(A表之外的表)进行增删改查;
- 对A表可以读,写需要等待会话1释放锁。
3、如果会话1对A表加了write锁,则该会话可以对A表进行任何增删改查操作;但是不能操作(增删改查)其他表;
4、其他会话对A表进行增删改查,必须等待A表释放锁。
MySQL表级锁的锁模式:
MyISAM: 在执行查询语句前,会自动给涉及到的所有表加读锁,在执行更新操作前,会自动个涉及的表加写锁。所以对MyISAM表进行操作,会有以下情况:
- 对MyISAM表的读操作(加读锁),不会阻塞其他进程(会话)对同一表的读请求,但会则塞对同一表的写请求。只有当读锁释放后,才会执行其他进程的写操作。
- 对MyISAM表的写操作(加写锁),会则塞其他进程(会话)对同一表的读和写操作,只有当写锁释放后,才会执行其他进程的读写操作。
分析表的锁定:
查看哪些表加了锁:show open tables; 1表示被加了锁
分析表锁定的严重程度:show status like ‘table%’;
Table_locks_immediate: 立刻能获取到的锁的表的个数;
Table_locks_waited:需要等待的表锁数(如果改值越大,说明存在越大的锁竞争)。
一般建议:
Table_locks_immediate / Table_locks_waited > 5000;建议采用InnoDB引擎,否则MyISAM引擎。