Mysql系列之锁机制

通常一个程序满,从消耗的角度,一个是cpu,一个是IO,但有的时候mysql慢,是由于某条sql不当心把整个表给锁了。mysql

什么是锁?

锁是计算机协调多个进程或线程并发访问某一资源的机制。
在数据库中,除了传统的计算机资源(如CPU,RAM,I/O)的争用外,数据也是供不少用户共享的资源。如何保证数据并发访问的一致性,有效性是全部数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。程序员

锁的分类?

从对数据操做的类型:分为读锁/写锁sql

  • 读锁(共享锁):针对同一份数据,多个读操做能够同时进行而不会互相影响
  • 写锁(排它锁):当写操做没有完成前,会阻断其它写锁和读锁

从对数据操做的粒度:分为表锁/行锁数据库

Mysql的三锁

表锁(偏读)

1.特色:偏向MyISAM存储引擎,开销小,加锁快,无死锁;锁定粒度大,发生锁冲突的几率最高,并发度最低
2.案例分析:session

  • 加读锁
  1. session1获取读锁,能够读取数据,session2也能够读取数据
  2. session1获取读锁,能够读取数据,可是当要向表中插入数据时,会报错,由于尚未释放读锁,可是session2向表中插入数据时,会处于等待状态,等session1释放读锁后,session2的写入操做就完成了
  • 加写锁
    1.session1加完写锁后,session1能够对表进行查询,插入,更新等操做,而此时session2对该表进行读或写操做时都会被阻塞

3.案例总结
MyISAM在执行查询语句以前,会自动给所涉及的表加读锁,在执行增改删操做前,会自动给涉及的表加写锁
MyISAM表级锁有两种模式:并发

  • 表共享读锁
  • 表独占写锁

结论:性能

  1. 对MyISAM表的读操做(加读锁),不会阻塞其它进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操做
  2. 对MyISAM表进行写操做(加写锁),会阻塞其它进程对同一表的读和写操做,只有当释放了写锁时,才会执行其它进程的读写操做

简而言之就是,读锁会阻塞写,但不会阻塞读,而写锁会阻塞读和写优化

4.表锁分析,如何排查锁的状况
看看哪些表被锁了:show open tables;
如何分析表锁定:能够经过table_locks_waited和table_locks_immediate状态变量来分析系统上的表锁定
SQL:show status like 'table%';spa

  • table_locks_immediate:产生表级锁定的次数,表示能够当即获取锁的查询次数,每当即得到取锁值加1;
  • table_locks_waited:出现表级锁定争用而发生的等待次数(不能当即获取锁的次数,每等待一次锁值加1),此值高则说明存在较严重的表级锁征用状况;

另外,MyISAM的读写锁调度是写优先,这也是MyISAM不适合作写为主表的引擎。由于写锁后,其它线程不能作任何操做,大量的更新会使查询很可贵到锁,从而形成永远阻塞线程

行锁(偏写)

1.特色:偏向InnoDB存储引擎,开销大,加锁慢,有死锁,锁定力度小,发生锁冲突的几率最低,并发度也最高
InnoDB与MyISAM二者的不一样:一是支持事务,而是采用了行级锁
2.并发事务处理带来的问题

  • 更新丢失:两个事务不知道彼此的存在,最后的更新覆盖了由其它事务所作的更新,若是在一个程序员完成并提交事务以前,另外一个程序员不能访问同一文件则能够解决
  • 脏读:事务A读取到了事务B已修改但还没有提交的数据,还在这个数据的基础上作了操做,此时,若是事务B回滚,A读取的数据无效,不符合一致性的要求
  • 不可重复读:事务A读取到了事务B已经提交的修改数据,不符合隔离性
  • 幻读:事务A读取到了事务B体提交的新增数据,不符合隔离性。幻读和脏读有点相似,脏读是事务B里面修改了数据,幻读是事务B里面新增了数据。

3.事务的隔离级别

clipboard.png

4.案例分析

5.无索引行锁升级为表锁

6.间隙锁的危害

7.分析行锁定
经过检查InnoDB_row_lock状态变量来分析系统上的行锁争夺状况
show status like 'innodb_row_lock%';

clipboard.png

8.优化建议

clipboard.png

页锁

clipboard.png

相关文章
相关标签/搜索