zoukankan      html  css  js  c++  java
  • MySQL优化(6):Mysql锁机制

    对数据操作的类型:

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

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

    对数据操作的粒度:

    表锁(偏读)—— 偏向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提交的新增数据。

    隔离级别:

       

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

    【情景1】

        session1                session2

        set autocommit=0;         set autocommit=0;

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

        提交                  解除阻塞,提交

    3、索引失效行锁变表锁

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

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

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

      

    5、如何锁定一行

    begin;
    select * fromwhere 条件 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。

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

     

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

     

  • 相关阅读:
    UVa 11181
    UVa 10491
    UVa 1636
    UVa 1262
    UVa 10820
    UVa 1635
    UVa 12716
    [2019杭电多校第六场][hdu6635]Nonsense Time
    [2019杭电多校第五场][hdu6630]permutation 2
    [2019杭电多校第五场][hdu6629]string matching(扩展kmp)
  • 原文地址:https://www.cnblogs.com/zjxiang/p/9164315.html
Copyright © 2011-2022 走看看