InnoDB|带你认识什么是MySQL的内存架构和索引说明( 二 )


全局临时表空间(ibtmp1)存储用户创建的临时表所做更改的回滚块

  1. Doublewrite Buffer
    是个存储区域 , InnoDB在将page写入InnoDB数据文件中的适当位置之前 , 会在其中写入从buffer pool中刷新的page 。 如果在page写的过程中有操作系统、存储子系统 , 或者mysqld的异常退出 , InnoDB可以在崩溃恢复期间从double buffer找到一个好的副本
  2. Redo Log
    是一种基于磁盘的数据结构 , 用于在崩溃恢复期间用于更正由于不完整的事务写入的数据 。 在异常停机前没有完成更新数据文件的修改 , 在初始化期间和接收连接之前会自动重放
    默认在磁盘上有ib_logfile0和ib_logfile1 。 MYSQL以循环方式写入redo log
  3. Undo Logs
    一个undo log是与单个读写事务关联的undo log记录集合 。 一个undo log记录包含了如何撤销一个事务对一条聚簇索引记录最近修改的信息 。 如果其他事务需要将原始事务视为一致性读的一部分 , 则会从undo log记录中检索出未修改的数据 。
    undo logs存在于undo log段里 , undo log段包含于回滚段里 , 回滚段驻留于system表空间、undo表空间和全局临时表空间
    驻留于全局临时表空间中的undo logs用于在用户定义的临时表里修改数据的事务 。 这些undo logs没有被redo logged , 因为崩溃恢复不需要它们 。 它们只用于在服务器运行期间回滚 。 这种类型的undo logs通过避免redo logging的IO而提升了性能
一个事务最多分配4个undo logs , 每个都是下面的操作类型之一:
  1. INSERT操作 , 用户定义的表
  2. UPDATE和DELETE操作 , 用户定义的表
  3. INSERT操作 , 用户定义的临时表
  4. UPDATE和DELETE操作 , 用户定义的临时表
InnoDB锁和事务模型InnoDB锁共享锁和排他锁
  • 共享锁 shared (s)锁
    允许持有锁的事务读取一行
  • 排他锁 exclusive (x)锁
    运行持有锁的事务更新或者删除行
意向锁 Intention Locks表级锁 , 用于指示事务稍后在表里需要哪种类型的锁(共享或排他)
  • intention shared lock (IS)表明事务将在表里独立的行上设置共享锁
  • intention exclusive lock (IX)表明事务将在表里独立的行上设置排他锁
SELECT … FOR SHARE设置IS锁 , SELECT … FOR UPDATE设置IX锁
事务在能获取表里行的共享锁之前 , 必须先获取表的IS锁或更强的锁
事务在能获取表里行的排他锁之前 , 必须先获取表的IX锁或更强的锁
记录锁 Record Locks在索引记录上的锁
记录锁始终锁定索引记录 , 即使表上没有定义索引 。 这种情况下 , InnoDB会创建一个隐式的聚簇索引 , 使用这个索引锁定记录
间隙锁 Gap Locks索引记录间隙之间的锁 , 或者第一个索引记录之前或最后一个索引记录之后的间隙的锁
e.g. SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;
会阻止其他事务插入15的值到t.c1列 , 而不用管在这个列中有没有这个值
对于使用唯一索引搜索唯一行的语句 , 不需要间隙锁 。 e.g.列id有唯一索引 , 下面这语句只对id=100的行使用索引记录锁 , 其他会话是否在前面的间隙中插入行并不重要
SELECT * FROM child WHERE id = 100;

如果id没有被索引 , 或者没有唯一索引 , 则语句会锁定前面的间隙
InnoDB的间隙锁是“纯抑制性的” , 它的唯一目的是阻止其他事务插入到这个间隙 , 间隙锁可以共存 , 共享和排他间隙锁没有差别
间隙锁是可以被禁用的 , 如果被禁用可能会导致幻读问题 , 因为其他session可以将新行插入间隙