26.MySQL 锁

MyISAM 的读写锁是自动加的。MyISAM 总是一次性获取 SQL 语句所需要的全部锁,所以不会出现死锁。 
写锁 :  如果对表进行了写锁,那么当前线程只能对锁定的表进行操作(读写)。
        其他线程不能对锁定的表进行操作(读写)。
lock table 表名 read/write local
local 表示允许其他用户在表尾并发插入记录, 没有 local 不能插入
读锁:
    当前线程可以读,不能写。
    其他线程可以读,不能写。
如果有别名,需要都锁住。
lock table test as a read, test as b read
MyISAM 的读写是串行的,这是总体而言。
一定条件下,MyISAM 也支持查询和插入的并发执行。
concurrent_insert = [0,1,2] // 0不允许;1允许,但没有空洞; 2允许,不管有没有空洞。 optimize table 表名 //除去空洞
锁调度:
      写进程优先。
      可以通过指定参数,降低写的优先级。
 
InnoDB 锁机制:意向锁自动加,update,delete,insert自动加排它锁。普通 select 不加锁。
共享锁: S   // select * from 表名 where ... lock in share mode
排他锁 : x   // select * from 表名 where ... for update
意向共享锁: IS
意向排它锁 : IX
共享锁:
当前线程可以select , update, insert ,delete
其他线程可以select,,delete,insert不能对锁定的行进行操作,会 block 住。 不同线程操作同一个记录,也会block.
其他线程也可以对该记录加读锁,加完后,当前线程就不能进行更新操作了。
排它锁:
当前线程可以增删查改
其他线程可以查, 增删改 不对那个记录就行。对同一个记录加锁,等待.
2个线程同时对一个记录加读锁,
并都去更新那个记录,则会发生死锁
!!!  InnoDB 的行锁是通过给索引上的索引项加锁实现的。
不是对响应的数据行进行加锁。
所以,不通过索引查询的时候,用的是表锁,而不是行锁。
虽然InnoDB是对行进行加锁
但是如果对不同行进行加锁时,用到了同相同的索引键,仍然会出现锁冲突。
当有多个索引时,不同的事务可以针对不同的行进行锁定。
但如果涉及到同一行,就block
即便在查询中使用了索引字段,但如果MySQL认为全表扫描更划算,就不用索引。这个时候,就不会用到行锁,转而使用表锁。
间隙锁:
   当我们用范围条件检索数据,而不是相等条件时,InnoDB 会结合条件对已有的数据加锁,
对在条件范围内,但不存在的记录也会加锁,这叫间隙锁。这是为了防止幻读。
   所以,记录锁住时,插入时会block
MySQL的恢复机制:
 1.恢复是Sql语句级别的,重新执行binlog中的sql
 2.binlog按照事务提交的顺序记录。实际上要求事务串行化,不允许幻读
InnoDB 什么情况下使用表锁:
  1.事务需要更新大部分或者全部的数据,会造成其他事务的锁等待和锁冲突
  2.事务涉及多个表,容易造成死锁,和大量的事务回滚。
InnoDB使用表锁需要注意:
  lock table 虽然可以给innodb 加表锁,但表锁不是由innodb存储引擎层管理的,是有 mysql server 负责的。
仅当,autocommit =0;innodb_table_locks = 1,innodb 层才知道mysql 加的表锁。
mysql server 也能感知 innodb 加的行锁,这种情况下innodb才能自动识别涉及表锁的死锁。否则无法处理这种死锁。

用 lock table 给 innodb 加表锁,需要 autocommit = 0,否则不给加。事务结束前,不要用 unlock table ,
因为 unlock table 会隐含的提交事务。所以需要先 commit ,在 unlock table.
死锁的避免:
  1.尽量以相同的顺序访问表
  2.程序批量处理数据时,先排序,保证每个线程按固定的顺序处理数据。
  3.在事务更新记录的时候,应直接申请足够的锁,即排它锁。而不是先申请共享锁,在申请排它锁。
  4.如果2个线程使用相同的sql进行加锁,但这个条件其实没有记录,如果这个时候,2个线程同时插入数据,就会造成死锁。这时,事务级别应改成 提交读。
show engine innodb status ;


1.概述



2.MyISAM 表锁


写锁 : 如果对表进行了写锁,那么当前线程只能对锁定的表进行操作。
       其他线程不能对锁定的表进行操作。






读锁 :  当前线程只能查询锁定的表,不能访问其他表,也不能插入,更新当前表
       其他线程可以查询,并发插入,不能更新,修改
有别名的,需要全部锁住别名


并发插入:



MyISAM 锁粒度:




3. InnoDB 锁问题



获取 innodb 行锁争用情况:


InnoDB 的行锁模式及加锁方法:




InnoDB 行锁实现方式:





间隙锁:



恢复和复制的需要,对 InnoDB 的影响:




InnoDB 在不同隔离级别下的一致性读及锁的差异




什么时候使用表锁:



关于死锁:




小结:



http://blog.csdn.net/zmx729618/article/details/51728654


https://mp.weixin.qq.com/s/qaotY7WJsRobhmMJ5bbkzg







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值