锁是计算机协调多个进程或线程并发访问某一资源的机制。
从对数据操作的类型分:读锁和写锁。偏向于MYISAM存储引擎。
读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响。
lock table stu read; 手动给表stu添加读锁。
unlock tables; 给所有表解锁。
show open tables; 查看所有表是否具有锁。
例1:假如在session_1上使用命令,lock table stu read; 获得表stu的read锁定,当前session_1只可以查询stu的记录,不能查看其他table的内容也不能修改stu及其他table的内容;而在session_2上可以查询stu表及其他table的内容,可以修改或更新其他table的内容,但是不能修改和更新stu的内容,直到session_1对stu的读锁解除。session_1 通过unlock tables; session_2对stu的更新生效。
写锁(排它锁):当前写操作没有完成前。它会阻断其他写锁和读锁。
例2:假如在session_1上使用命令,lock table stu write;获得表stu的write锁定,当前session_1可以对stu表进行查询和修改,但是不能对其他表进行查询和修改。而在session_2上,可以对其他表进行查询和修改,但是对stu表进行查询是处于一个堵塞的状态,只有当在session_1中unlock tables之后才会接触session_2对stu表的堵塞状态。
总结:1、对表添加读锁,不会堵塞其他进程对同一表的读请求,但会堵塞对同一表的写请求。只有当读锁释放后,才会执行其他进程的写操作。
2、对表添加写锁,会堵塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其他进程的读写操作。
总而言之:读锁会堵塞写,但是不会阻塞读;而写锁则会把读和写都堵塞、
从对数据操作的粒度分:表锁和行锁 ,偏向于InnoDB存储引擎。
行锁偏向Innodb存储引擎,开销大,枷锁man;会出现死锁;锁定粒度最小,发生所冲突的概率最低,并发度也最高。
InnoDB与MyISAM的最大不同有两点:一是支持事务(transaction);二是采用了行级锁。
事务(复习):事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,即ACID。
原子性(Atomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。
一致性(Cosistent):在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事物的修改,以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引或双向链表)也都必须是正确的。
隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处理过程中的中间装填对外部是不可见的,反之亦然。
持久性(Durable):事务完成之后,他对数据的修改是永久性的,及时出现系统故障也能够保持。
不同的行锁之间互不干扰。
innodb存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面所带来的性能损耗可能比表级锁定回要更高一些,但是在整体并发处理能力方面要远远优于MyISAM的表级锁定。当系统并发量较高的时候,Innodb的整体性能和myisam相比就会有比较明显的优势。
但是,innodb的行级锁定同样也有其脆弱的一面,当我们使用不当的时候,可能会让innodb的整体性能表现不仅不能比myisam高,甚至可能会更差。
行锁可能会导致表锁:当使用类型不当索引时,行锁会变成表锁。
间隙锁:当我们用范围条件而不是相等条件检索数据,并请求共享或排它锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”
InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key锁)。
如何锁定一行:
InnoDB存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面带来的性能损耗可能比标记锁定会要更高一些,但是在整体并发处理能力方面要远远由于MyISAM的表级锁定的。当系统并发量较高的时候,InnoDB的整体性能和MyISAM相比就会有比较明显的优势了。
但是,InnoDB的行级锁定同样具有其脆弱的一面,当我们使用不当的时候,可能会让InnoDB的整体性能表现不仅不能比MyISAM高,甚至可能会更差。
使用命令show status like 'innodb_row_lock%';
其中第一个表示当前正在等待锁定的数量,第二个表示从系统启动到现在锁定总时间长度,第三个表示每次等待所花的平均时间,第四个表示从系统启动到现在等待最长的一次所化的时间是多少。第五个表示系统启动后到现在总共等待的次数。
如果上述的标准等待时间较长,可通过使用show profile来查看具体的等待事项。
(show profiles复习:)
首先使用命令show variables like 'profiling';查看profiling的状态为ON还是为OFF,若为OFF,则通过set profiling=on;打开。
打开之后既可以使用show profiles;。
总结:行锁的优化建议:
1.尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁。
2.合理设计索引,尽可能缩小锁的范围。
3.尽可能较少检索条件,避免间隙锁。
4.尽量控制食物大小,减少锁定资源和时间长度。
5.尽可能低级别事务隔离。