MySQL的锁、索引、隔离级别与实现方式

1.锁的类型

InnoDB共有七种类型的锁:

  • 共享/排它锁(Shared and Exclusive Locks) 行级读写锁
    • 共享锁(Share Locks,记为S锁),读取数据时加S锁,
    • 排他锁(eXclusive Locks,记为X锁)修改数据时加X锁
  • 意向锁(Intention Locks) 表级
    • 意向共享锁(intention shared lock, IS),它预示着,事务有意向对表中的某些行加共享S锁;
    • 意向排它锁(intention exclusive lock, IX),它预示着,事务有意向对表中的某些行加排它X锁;
    • 事务要获得某些行的S/X锁,必须先获得表对应的IS/IX锁
  • 记录锁(Record Locks)行级
    • *索引记录
  • 间隙锁(Gap Locks)行级
    • RR以上级别
    • *索引记录中的间隔,或者第一条索引记录之前的范围,又或者最后一条索引记录之后的范围
  • 临键锁(Next-key Locks) 行级
    • 避免幻读,RR以上级别
    • 记录锁与间隙锁的组合,它的*范围,既包含索引记录,又包含索引区间,左开右闭
    • innodb使用Next-Key Locks来锁定记录。但当查询的索引含有唯一属性的时候,Next-Key Lock 会进行优化,将其降级为Record Lock,即仅锁住索引本身,不是范围
  • 插入意向锁(Insert Intention Locks) 行级
    • 间隙锁(Gap Locks)的一种
  • 自增锁(Auto-inc Locks)特殊的表级别锁
    • 用于处理自增主键

2.MySQL索引

  • 普通索引:允许在定义索引的列中插入重复值和空值
  • 唯一性索引:值必须唯一,允许有空值,如果是组合索引,则列值的组合必须唯一
  • 主键索引:特殊的唯一索引,不允许值重复或者值为空
  • 全文索引:用来查找文本中的关键字

3.MySQL隔离级别与实现方式

隔离级别

出现问题

实现方式

普通select

locking select/update/delete会

读未提交(Read Uncommitted)

脏读

select语句不加锁,也不是快照读

读已提交(Read Committed)

不可重复读

(其他已提交事务的update和delete)

最新的快照读(MVCC)

加记录锁(recording lock)

可重复读(Repeated Read)

默认模式

幻读

(其他已提交事务的insert)

本事务第一次的快照读(MVCC)

符合唯一索引配合唯一查询条件,加记录锁

符合范围查询或非唯一索引使用间隙锁(gap lock)与临键锁(next-key lock),可避免幻读

串行化(Serializable)

效率低

默认都加读锁

MySQL的锁、索引、隔离级别与实现方式

上一篇:TCP文件上传


下一篇:MySQL-InnoDB聚簇索引与非聚簇索引