你需要知道的InnoDB引擎100问

Innodb读书笔记

第一章 体系结构与存储引擎

  1. 介绍Innodb的存储引擎
    InnoDB:支持事务,主要是面向在线事务处理(online transaction processing OLTP 对应的还有OLAP, online analytical processing 在线分析处理 更多用在数仓上,需要负载的sql语句。)的应用。 InnnDB通过MVCC来获得高并发性,实现了sql的四种隔离级别,默认为 可重复读 。同时,使用next-key-locking来避免幻读的出现。除此以外,还包括了 插入缓冲(insert buff)、二次写(double write)、自适应哈希索引(adaptive hash index)、预读(read ahead) 等高可用高性能功能。

  2. 如果没有显式的指定主键innoDB会如何?
    对于表中数据,InnoDB采用了聚集方式,因此表都按照主键的顺序存放。如果没有显式的指定主键,先看有没有非空唯一索引,如果有就是主键。否则会默认为每一行生成一个6字节的ROWID,并作为主键。

  3. 介绍其他存储引擎

  • MyISAM引擎,不支持事务、表锁,支持全文索引。主要面向一些OLAP应用。主要是抽取(extract)、转换(transform)、加载(load)ETL操作。并且这个引擎只缓存索引文件,不缓存数据文件。
  • Memory引擎,默认使用哈希索引,而不是熟悉的B+数。Mysql使用Memory引擎作为临时表来存放查询的中间结果集。

使用不同的存储引擎,得到的表大小也不同。

第二章 InnoDB引擎

  1. 介绍下InnoDB体系架构

InnoDB有多个内存块,可以认为这些内存块组成了一个大的内存池,负责维护进程/线程需要的内部数据结构、缓存磁盘的数据、redo log缓冲
在这里插入图片描述

  1. 介绍下后台线程吧

    1. Master Tread:核心线程,负责将缓冲池的数据异步落盘,包括脏页刷新、合并插入缓冲(insert buffer)、undo页回收。
    2. IO thread:使用了AIO来处理IO请求,主要是负责IO请求的回调。包括四个线程,write、read、insert buffer、log IO thread。
    3. Purge thread:事务提交以后,undolog不在需要,这个线程用于回收已使用的undolog页。
    4. page cleaner thread:单独进行脏页的刷新。
  2. 介绍下内存池吧

    1. 缓冲池:从磁盘读到的页放在缓存池中,下次再请求先查询。从缓冲池落盘的操作不是每次都进行,而是利用checkpoint机制。缓存的类型如下图:大头是索引页和数据页,还有部分是插入缓冲和锁信息、自适应哈希索引等。
      在这里插入图片描述
    2. LRU、Free、Flush list:LRU进行管理,最频繁使用页放在队头,最少使用在队尾。并且有一个midpoint,防止一些全表扫描刷出去常用页,因此LRU可以被分为冷端和热端。在一定的时间后,冷端内容被刷到热端。Free list表示空闲的可以加入LRU的页。一般命中率不能低于95%,否则需要看看是不是因为全表扫描被污染了。Flush list记录了脏页。也就是脏页既在flush,也在lru中。
    3. redo log buffer:redolog每秒被刷回盘一次、或者事务提交时候、或者redo log buffer剩余空间小于1/2。redolog是可以重复使用的。
  3. 什么是checkpoint
    为了避免数据丢失,一般事务数据库都使用WAL技术,即事务提交时,先写redo log,再修改页。Checkpoint是为了:缩短数据库恢复时间、缓冲池不够时,脏页落盘、redolog满了时候,脏页数据落盘,清理redolog。

  4. 什么是LSN(log sequence number)
    标记版本,8字节的数字,每个页有,重做日志也有,checkpoints也有。

  5. 何时出发checkpoint?
    数据库关闭时触发sharp checkpoint,落盘全部脏页。平时一般Fuzzy checkpoints,包括 主线程定期落盘、 LRU满了弹出脏页需要落盘(page clean thread)、 redolog满了需要刷回(page clean thread)、 数据页缓冲池满了。

  6. 什么是insert buffer?
    核心是将 随机写 变为 顺序写,适用范围 索引是辅助索引、索引不是唯一索引。聚集索引一般是顺序写的,而辅助一般是离散的。而非聚集索引的插入很容易不是顺序的;唯一索引需要查表验证,因此也不能。因此,对于非聚集索引的插入和更新,先判断非聚集索引页在不在缓冲池中,如果在直接插入;若不在,先加入insert buffer中。随后以一定的频率将insert buffer和辅助索引页子节点的merge,这时候往往可以将多个操作合并为一个。 存在的问题:宕机以后恢复很慢,因为没有实际的落盘。以及写密集情况下占用的缓冲池内存太多。使用了一个bitmap存储了辅助索引页的存在性和空间等信息。

  7. insert buffer的原理
    使用了一个B+树,非叶节点是search key,维护了需要插入的表id。叶子节点记录了实际需要插入的字段。执行实际插入的时间有三个:1. 辅助索引页被读取到缓冲池,bitmap发现该辅助索引页已经无空间,master thread。

  8. 自适应哈希
    InnoDB会监控表上各索引页的查询。如果观察到建立hash索引可以来带速度提升,则建立hash索引,称为自适应哈希。比如经常进行同一个索引的读写。

  9. 刷新邻接页 Flush Neighbor Page
    刷新一个脏页时候,会检测该页所在区的所有页,如果是脏页,连带一起刷新。将多次IO变成一次。使用与机械硬盘,对于高性能的固态其实没必要。

第五章 索引与算法

  1. InnoDB有哪些常见索引?
    B+树索引,全文索引,哈希索引。其中哈希索引是自适应的,无法人为干预。B+树索引主要是查找到数据所在的页,然后数据库将页读入内存,再内存中找到对应的数据行。

  2. B+树的索引有哪些特点?

    • 高扇出特性,B+树本质是一个多叉树,一般在数据库中树的高度是24层,这保证了查找某一键值的行记录最多只需要24次。
    • 聚集索引与非聚集索引:聚集索引是按照表的主键简历的B+树,叶节点存放的是整张表的行记录数据,叶节点也可以称为数据页。 数据页是按照B+树进行排序的。而非聚集索引也就是辅助索引,存放的是键值指向数据页的偏移量。
  3. 聚集索引的存储是不是物理上连续的?
    不是的。是逻辑上连续的,因为是双向链表链接的,页按照主键的顺序排序,因此没必要物理上连续。

  4. 辅助索引上叶节点存放的是什么?辅助索引的查找过程是怎样的。
    存放的是一个书签,对应相应的行数据的聚集索引键。 通过辅助索引来寻找数据时候,引擎会遍历辅助索引并通过页指针得到指向主键索引的主键,然后通过主键索引来找到完整的行记录(回表)。对于一个高度为3的辅助索引树和主键索引树,一次辅助索引的查找需要6次IO,三次在辅助索引树上,三次在主索引树上。最终得到一个数据页。

  5. 什么是联合索引?
    就是对于多个列建立的索引。合理使用联合索引可减少一次排序。

  6. 联合索引的使用场景和不适用场景
    建立(a,b)的联合索引,有a的单独索引

    • 只查询a,可以使用联合索引。但是优先使用a的单独索引,因为一页可以放下的记录更多,IO更少。
    • where a = 10 and b >15 或者 where a = 10 order by b DESC limit 3 优先使用联合索引,可以减少一次排序。
  7. 覆盖索引是什么?为什么要使用辅助索引
    从辅助索引就可以得到的查询记录就不要去聚集索引里面查找(不需要回表的,比如count(*))。因此辅助索引不包含整行的所有信息,因此大小远小于聚集索引,大大减少IO操作。
    eg:辅助索引叶节点包含了主键信息,叶节点存放的内容为(primary key1, primary key2,…, key1, key2)。下列语句都可以使用辅助索引

    select key2 from t where key1 = xxx;
    select primary key2, key2 from t where key1 = xxx;
    select primary key1, key2 from t where key1 = xxx;
    select primary key1, primary key2, key2 from t where key1 = xxx;
    

    以及,对于统计一般也是使用辅助索引。比如select count(*) from buy_log。这样可以减少IO操作。举一个特殊例子,如果是统计操作,且索引覆盖,优化器可以进行使用联合索引。

    select count(*) from buy_log where a>='2011-01-01' and a<'2011-02-01'
    

    对(usrid, a)有联合索引,按理说不会走,但是因为是统计,并且是覆盖索引,因此可以使用联合索引。
    对于不能索引覆盖的情况,选择辅助索引的情况是通过辅助索引查找的数据是少量的。

  8. 什么时候会不使用索引呢?
    有时候会通过扫描聚集索引,也就是全表扫来完成某些操作。主要是范围查找等。

    select * from t where b>100 and b<12000;
    

    表上包括(b,c)的联合主键,还有b的辅助索引。但是结果上是使用的表扫描的方法。因为需要的是整行的信息,b的辅助索引无法索引覆盖,需要回表的过程是离散读。这里就会使用聚集索引来读取数据,因为顺序读更快。

  9. InnoDB支持全文索引么?
    支持,首先B+树就是可以通过索引字段的前缀进行查找的。比如 like 'xxx%'可以通过索引字段的。另外,全文索引一般是通过倒排索引实现的,在辅助表中存储了单词与单词自身在文档中的位置映射。

第六章 锁

  1. 为什么数据库需要使用锁?
    数据库锁的使用是为了支持对共享资源进行并发访问,保证数据的完整性和一致性。

  2. 数据库中lock和latch的区别
    lock的对象是事务,锁定的是数据库中的对象,一般会在commit或者rollback以后释放。latch的对象是线程,保护内存数据结构,持续时间是临界资源被保护的时间。

  3. 锁的类型有哪些?

    • 共享锁S/排他锁X 行级别的锁
    • 意向锁 表级别的锁
  4. 什么是一致性锁定读?

    • 概念:在读已提交可重复读场景下,如果读取的行正在被Delete或者update加上了X锁。此时InnoDB去读取一个快照数据,而不是等待。
    • 原理/实现:通过MVCC实现。
    • 特点:提高了并发性能,是默认读取方式,但是不同的事务隔离级别下,读取的MVCC的方法不同。以及不是所有的事务下都是 一致性非锁定读。
      • 读已提交:总是读取被锁定行的最新一份快照数据
      • 可重复读:读取事务开始时候的行数据版本。
  5. 什么是一致性锁定读?

    • 概念:通过对数据库加锁保证数据逻辑一致性。对于select语句有两种支持一致性锁定读的操作:
    select ... for update // 对读取行加一个X锁
    select ... lock in share mode // 对读取行记录加一个S锁
    
  6. 锁的算法有哪些?

    • record lock:对单行上锁
    • gap lock:间隙锁
    • next-key lock:锁一个范围加记录本身。其中当查询索引是唯一索引时,next-keylock降级为单行锁。 同时需要注意,对于辅助索引上的间隙锁,在主键索引上会锁住行锁。如果唯一索引是多个列,查询其中多个唯一索引列中的一个,依然使用next-key lock。
  7. 锁问题有哪些?

    • 脏读:事务对缓冲池中行记录的修改,并且还没被提交导致的脏数据被其它事务读取到。 违反了隔离性。 发生条件:读未提交 解决办法:读已提交。
    • 不可重复读:因为其他事务的DML修改,导致当前事务多次读取的数据不同。违反了一致性要求。发生条件:读已提交 解决办法:可重复读
    • 幻读:一个事务中,两次查询不同,其中,第二次查询会返回之前不存在的行。 解决方法:可重复读,使用间隙锁。
    • 丢失更新:一个事务的更新被另外一个事务覆盖。 解决方法:串行化,对读取的记录加X锁。
  8. InnoDB如何处理异常的?死锁的回滚了解么?

    • 默认情况下,InnoDB不会回滚 超时引发的错误异常。因此用户需要自己处理超时以后是commit操作还是rollback。
    • 死锁引发的一场InnoDB是会回滚的。
  9. InnoDB存在锁升级么?
    不存在。

第七章 事务

  1. 为什么要有事务?
    事务是区分数据库和文件系统的重要特征之一。对于文件系统,如果写文件的过程中,系统崩溃了,有一定的机制可以让系统恢复到某个时刻的状态。但是,无法实现文件的同步,比如更新A以后更新B的过程中失败了,就可能导致两个不同步的文件。事务的定义是:把数据库从一种一致状态转换为另外一种一致状态。 也就是要么所有修改都保存了,要不都不保存。

  2. InnoDB中事务的四个属性是如何解决的?

    • A 原子性:使用redo log。
    • C 一致性:如果事务中的某个动作失败了,系统可以自动撤销事务并返回初始状态。利用undo log。
    • I 隔离性:通过各种锁,MVCC,串行化的方法。
    • D 持久性:通过redo log,bin log等。
  3. 事务的类型有哪些?

    • 扁平事务:最简单的事务模型,要不完成要不全部回滚。
    • 带有保存点的扁平事务:相当于一个可以存档的事务类型。这里的保存点都是易失的,如果崩溃依然无法恢复。
    • 链事务:提交一个事务的时候,释放不需要的数据对象(包括锁),然后需要的上下文隐式的传递给下一个开始的事务。需要注意的是,对于链事务只能回滚到最近的一个保存点。
    • 分布式事务:调用多台数据库完成任务。需要在多台数据库之间达成同步。
  4. 什么是redo log
    重做日志,两部分组成:一个是内存中的缓存 redo log buffer 是易失的,一个是重做日志文件redo log file是持久的。
    在进行事务提交的时候,先将事务的所有日志文件写到重做日志文件进行持久化,然后事务提交。这里的日志包括了undo log 和redo log。redo log都是顺序写一般不需要读,undo log则可能随机读。

  5. 什么是bin log?binlog和redo log有什么不同?
    binlog是二进制日志,可以用户恢复和主从复制。

    • redo/undo log是在存储引擎产生的,binlog则是更高的数据库层。
    • 记录内容不同:binlog记录的是sql语句,是逻辑日志。 redolog是物理日志,记录的是队每个页的修改。
    • 落盘时间不同:binlog在事务提交以后一次写入。redo/undo 是在事务进行中不断被写入。
    • 恢复时:优先使用物理日志redo log
  6. 什么是undo log?
    undo log是逻辑日志,将数据库逻辑的恢复到原来的样子。因为存在并发,所以是不可能物理恢复的(A线程和B线程同时修改,只能回退A的)。undo存放在数据库的一个特殊段内undo 段,在共享表空间中。除了用户回滚,可以用用于MVCC,可以读取到这一行之前的行版本信息。当然undo 的产生也会伴随redo 的产生。因为其实是逻辑存储了undo 日志。

  7. 什么时候可以删除undo log?
    undolog 可以分为两种,insert undolog和update undolog。其中insert操作的记录只对事务本身可见,其他事务不可见,因此在事务提交以后就可以直接删除。而update undo log是对delete和update的操作,需要提供MVCC给其他事务。需要在事务提交以后放入undo log链表,等待purge线程删除。对于一个undo log 不在可能被使用的时候,才会被删除。

  8. 什么是两阶段事务?
    为了保证事务和二进制日志的一致性,采用了两阶段事务2PC

    • 当事务提交时,InnoDB存储引擎进行prepare操作。
    • mysql数据库上层写入binlog
    • 存储引擎层写入重做日志
      • 组提交的两步
        一般步骤2的操作完成,就确保了事务的提交。
        在这里插入图片描述
  9. 了解组提交group commit么?
    对于事务提交会分为两个阶段:

  • 修改内存中事务对应信息,并将日志写入重做日志缓冲。
  • 调用fsync将确保日志都从重做日志缓冲写入磁盘。
    其中步骤2比较慢,因此在可以在多个事务的步骤1完成以后,一次fsync降低写盘次数。
    对于采用binlog的数据库,采用这种思路
  • Flush阶段:将每个事务的二进制日志写入内存
  • Sync阶段,将内存的二进制日志刷新到磁盘中,如果队列中有多个事务,一次刷盘就可以完成全部binlog写入。。
  • Commit阶段,leader根据顺序调用存储引擎层事务的提交。
    有一组事务在commit阶段的时候,其他新事务可以进行flush。
  1. 数据库的内部XA事务保证主从一致性
    当事务提交时候,存储引擎首先进行一个prepare操作,将事务的xid写入,然后写binlog。如果在redo log提交前,系统宕机了,mysql在重启以后先检查准备的uxid是否已经提交,若没有,引擎层再进行一次提交。
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值