对数据操作的类型:

读锁(共享锁)—— 同一数据,多个读操作可以同时进行

写锁(排他锁)—— 写操作未完成前,会阻断其他读锁和写锁

对数据操作的粒度:

表锁(偏读)—— 偏向MyISAM存储引擎,开销小,加锁快,无死锁,锁定粒度大,发生锁冲突的概率最高,并发度最低。

行锁(偏写)—— 偏向InnoDB存储引擎,开销大,加锁慢,会出现死锁,锁定粒度小,发生锁冲突的概率最低,并发度也最高。

一、表锁操作

MyISAM引擎用表锁较多(偏读)

1、表锁语句

(1)加锁:假如给表mylock加读锁,表book加写锁
    lock table mylock read,book write;
(2)查看加锁的表,In_use=1表示加了锁
    show open tables; 
(3)查看Mysql内部表级锁定情况
    show status like 'table%';
    table_locks_immediate:产生表锁的次数
    table_locks_waited:出现表锁争用而发生等待的次数(每等待一次+1),值高说明争用表锁严重
(4)解所有锁
    unlock tables;



2、在MyISAM引擎下,表锁冲突演示

【情景1】:在session1为表1加读锁

    session1              session2

    能读表1                能读表1

    不能读其他未锁表,要先释放表1锁        能读或写其他未锁表

    不能写表1,报错            写表1会阻塞

【情景2】:在session1为表1加写锁

    session1                session2

    能读表1                读表1会阻塞

    不能读其他未锁表,要先释放表1锁        能读或写其他未锁表

    能写表1                写表1会阻塞

 

结论:读锁会阻塞写,但不阻塞读。写锁会阻塞读写。

     MyISAM在select前,会自动给涉及的所有表加读锁,在执行增删改操作前,会自动给涉及表加写锁。

     MyISAM的读写锁调度写优先,大量更新会使查询很难得到锁,因此不适合做写为主的引擎。

二、行锁操作

InnoDB与MyISAM的最大不同有两点:一是支持事务,二是采用了行级锁

1、并发问题:

(1)更新丢失 —— 由于事务间不知道其他事务的存在,会发生覆盖其他事务更新的情况,如果在一个程序员完成并提交事务前,另一个程序员不能访问同一文件,则可避免此问题。

(2)脏读 —— 事务A读取到了事务B已修改但未提交的数据,如果B回滚,A读的数据无效。

(3)不可重复读 —— 某事务两次读取的数据不一致。

(4)幻读 —— 事务A读取到事务B提交的新增数据。

隔离级别:

   

mysql innodb什么情况会造成锁表 mysql什么操作会锁表_数据库

2、在Innodb引擎下,行锁冲突演示,Innodb默认是行锁

【情景1】

    session1                session2

    set autocommit=0;         set autocommit=0;

    更新但不提交,未commit       更新同一行时会阻塞,更新不同行不会阻塞

    提交                  解除阻塞,提交

3、索引失效行锁变表锁

  若session1执行的写操作造成索引失效,会从行锁变为表锁,其他session对表写会阻塞

4、间隙锁带来的插入问题

  用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会锁定整个范围内所有的索引键值,即使这个键值不存在,而锁定范围时无法在锁定键值范围内插入数据,某些场景下可能存在危害。   

  

mysql innodb什么情况会造成锁表 mysql什么操作会锁表_数据库_02

5、如何锁定一行



begin;
select * from 表 where 条件 for update;
commit;
#通过for update锁定某行后,其他的操作会被阻塞,直到锁定行的会话提交commit



6、查看行锁信息:



show status like 'innodb_row_lock%';
#Innodb_row_lock_current_waits:当前正在等待锁定的数量
#Innodb_row_lock_time:从系统启动到现在锁定总时间长度
#Innodb_row_lock_time_avg:每次等待所花平均时间
#Innodb_row_lock_time_max:从系统启动到现在等待最长的一次所花的时间
#Innodb_row_lock_waits:系统启动后到现在总共等待的次数



7、结论

  Innodb存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面所带来的性能损耗可能比表锁更高一些,但在整体并发处理能力方面远远优于MyISAM的表锁,当系统并发量较高时,Innodb明显优于MyISAM。

  优化建议:尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁。

 

*页锁:开销和加锁时间界于表锁和行锁之间,会出现死锁,锁粒度界于表锁和行锁之间,并发度一般。