zoukankan      html  css  js  c++  java
  • innodb锁

    默认是行锁(row lock)
    InnoDB是通过在索引记录上加锁,实现行锁
    因此,没有索引时就无法实现行锁,而升级成全表记录锁,等同于表锁
    锁类型
    a、共享锁
    b、排他锁
    c、意向锁,InnoDB特有,加载在表级别上的锁

     

    MDL

     

    全局锁:

    a,global read lock

    b,query cache lock

    mdl表锁

    自增互斥量(mutex),用来管理Auto-increment

    innoDB自旋锁,spinlock

     

    system lock:文件系统级别锁,frm文件。

     
     
     
     
    global read lock
    加锁:FTWRL,FLUSH TABLES WITH READ LOCK,
    关闭实例下的所有表,并加上全局读锁,防止被修改,直到提交UNLOCK TABLES,
    一般用于备份,mysqldump、xtrabackup都会发起,
    xtrabackup时可分开备份InnoDB和MyISAM,或者不执行 -- master-data
     
     
    query cache lock
    全局query cache锁,最好关闭
     
    对QC中的数据有更新时,都会引发query cache lock
    状态:Waiting for query cache lock
    关闭query cache
    query_cache_size = 0 & query_cache_type = 0
     
    MDL,meta data lock,事务内的表级锁,
    5.6.6前,事务开启后,会锁定表的meta data lock,其他会话对表有DDL操作时,均需等待mdl释放后方可继续
     
    5.6.6后,不再阻塞其他会话执行DDL,但原来的会话再次访问数据表时,会有error提示:Table definition has changed, please retry transaction,
    超时阈值定义:lock_wait_timeout
     
    自增锁,其实是个轻量级的互斥量(MUTEX),相关选项 innodb_autoinc_lock_mode,
    1 ,默认设置,可预判行数时使用新方式,不可预判时仍旧使用表锁,会造成autoinc列自增空洞,不过影响很小,
    0 ,即沿用旧的表级锁模式,每次请求都会等待表锁,不过也非常快。不会影响整个事务,只影响当前的INSERT语句。
    2 ,直接全部使用新方式,不安全,不适合replication环境
     
    InnoDB spin lock,自旋锁,innodb_spin_wait_delay,控制轮训间隔,默认6秒,
    show engine innodb status :
    Mutex spin waits 5870888, rounds 19812448, OS waits 375285
    事务并发非常高,CPU忙不过来的时候,事务处于sleep状态,spin round可能也会很高
    获得mutex的过程:
    尝试获取mutex锁,如果已经被其他人锁定了,则会不断尝试:你的锁空出来了吗(这个过程叫做spin wait),多次尝试后,发现还是不行就放弃抵抗进入sleep状态,直到这个mutex 锁被释放了。
    ** Mutex spin waits 5870888,线程尝试获取spin锁而不可得的次数,也就是 spin-wait 的次数
    ** rounds 19812448 ,线程进入spin wait循环的次数,也就是检查 mutex 锁的次数
    ** OS waits 375285,线程放弃spip wait尝试,直接进入sleep状态的次数
     
    innodb共享锁:
    a,共享锁,不允许其他事物修改被锁定的行
    b,select ... lock in share mode
    c,或者是在事物中普通select
    d,不在事物中的select是一致性非锁定读,不加锁。
     
    InnoDB锁之排他锁,
    对一行记录进行DML时,需至少加上排它锁,
    锁范围视情况而定,可能是record lock、next-key lock,或者可能只有gap lock,
    执行DML,或SELECT…FOR UPDATE,

    innodb排它锁:

    a,对一行记录进行DML时,需至少加上排它锁

    b,锁范围视情况而定,可能是record lock、next-keylock,或者可能只有gap lock

    执行DML.或select ...for update。

     

    InnoDB锁之意向锁
    IS,事务T想要获得表中某几行的共享锁
    IX,事务T想要获得表中某几行的排他锁
     
    意向锁是加载在数据表B+树结构的根节点,也就是对整个表加意向锁,
    意向锁的作用:避免在执行DML时,对表执行DDL操作,导致数据不一致
     
    执行DDL,要扫描所有锁吧?如果加在聚集索引的根节点上就不需要扫描全表。意向锁加在btree根节点,
     
     
     
     
     
     
     
    pt-osc:
    先创建一样的表:create table like xx;
    用触发器的方式将所有数据复制过来:create triggers,触发器的作用是保证数据更新同样搞过来。
    最后把lock table,把表锁住,将最新数据拷贝过来。再改名,解锁。
     
     

     

    无索引情况下,锁升级

    全部 name = ? 的记录都会被锁定,对整张表的行记录加锁,next key lock 每个记录加一把锁,也就是btree的叶子节点。等同于表锁
  • 相关阅读:
    linux之awk命令
    HDU 2097 Sky数 进制转换
    HDU 2077 汉诺塔IV
    HDU 2094 产生冠军 dfs加map容器
    HDU 2073 叠框
    HDU 2083 简易版之最短距离
    HDU 2063 过山车 二分匹配
    天梯 1014 装箱问题
    天梯 1214 线段覆盖
    天梯 1098 均分纸牌
  • 原文地址:https://www.cnblogs.com/xxmysql/p/5990306.html
Copyright © 2011-2022 走看看