innodb技术核心摘录

技术内幕-innodb

  • 1Memory 存储引擎默认使用哈希索引,而不是 B+ Tree索引,不支持 TEXT 和 BLOB 列类型。

  • 2MySQL 数据库使用 Memory 存储引擎作为临时表来存放查询的中间结果集。如果中间结果集大于 Memory 存储引擎表的容量设置,又或者中间结果含有 TEXT 或者 BLOB 字段,则 MySQL 数据库会把其转换成 MyISAM 存储引擎表而存在磁盘中。MyISAM 不缓存数据文件,因此这时产生的临时表的性能对于查询会有损失。

  • 3Innodb 内存数据对象包括 缓冲池(innodb_buffer_pool)、重做日志缓冲(redo_log_buffer)、额外内存池(innodb_additional_mem_pool_size)。

  • 4缓冲池(innodb_buffer_pool)不仅仅包含索引页(index page)、数据页(data page) 还包括 插入缓冲(insert buffer)、锁信息(lock info)、自适应哈希索引、数据字典信息。

  • 5在 InnoDB 存储引擎中,缓冲池中页的大小默认为 16 KB,使用 LRU 算法对缓冲池进行管理。

  • 6对普通的 LRU 算法进行了改进,加入了 midpoint 位置。把 LRU 列表一分为二,前面 5/8 是 new 列表,后面 3/8 是 old 列表,从磁盘新读入的页放在距离尾部 3/8 的位置(参数innodb_old_blocks_pct 默认值为 37 表示新读取的页插入到LRU列表尾端的37% 的位置差不多 3/8 的位置),可以防止在某个全表扫描的查询把之前的热数据缓存全部剔除。关于何时将数据从 old 列表放到 new 列表中,书上说通过另一个参数 innodb_old_blocks_time,用于表示页读取到 mid 位置需要等待多久才会加入到 new 列表中。在网上看到一个更靠谱的说法,当页在缓存中被第二次引用,即放到 new 列表的头部。大概是不同版本的不同实现,参考链接 https://arpitbhayani.me/blogs/mysql-cache。

  • 7数据库更新操作采用 Write Ahead Log 策略,先写 redo log(宕机时用于恢复数据),再更新缓冲池。一条 DML 语句更新了缓冲池中的页数据,导致和磁盘页数据不一致称为脏页。

  • 8为避免每次更新都将脏页刷回磁盘带来的性能损耗,使用 Checkpoint(检查点) 技术将脏页刷回磁盘。对于 InnoDB 使用 LSN(Log Sequence Number) 来标记版本。每个页、重做日志、Checkpoint 中都有 LSN, Checkpoint 之前的页都已经刷回磁盘,异常恢复只需要从 Checkpoint 之后恢复。主线程定时触发、LRU 空闲页不够、重做日志不可用、脏页太多都会触发 Checkpoint。

  • 9重做日志缓冲刷盘时机:
    1)主线程每隔 1s 将重做日志缓冲刷新到重做日志文件,即使事务没有提交,这也是为什么再大的事务提交时间都很短的原因
    2)每个事务提交时,由参数 innodb_flush_log_at_trx_commit 控制,为了保证事务的 ACID 中的持久性,必须设置为 1,表示在执行 commit 时将重做日志缓冲同步到磁盘,即伴有 fsync 的调用。
    3)重做日志缓冲区空间不足 1/2
    4)按 512字节(磁盘一个扇区的大小) 为单位进行写入。因为磁盘扇区是写入的最小单位,可以确保原子性,所以不需要double write

  • 10插入缓冲(Insert Buffer)
    B+ 树实现,主要解决非唯一二级索引插入性能低(非顺序插入)的问题,不直接操作索引页,在 Insert Buffer 中暂存,再通过一定的触发机制合并操作。

  • 11两次写(double write)
    解决部分写失效(partial page write),比如一页 16k 数据刷盘时只成功了 4k,崩溃时无法通过 redo log 恢复的问题。在对缓冲池脏页刷新时,不直接写磁盘,通过 memcpy 函数复制到 doublewrite buffer 中,然后通过顺序写入共享表空间中,最后再去从 doublewrite buffer 中 fsync 刷到磁盘。如果出现部分写失效恢复数据的时候,会从共享表空间中还原该页再进行恢复。

  • 12binlog 三种格式
    Statement:sql 的逻辑语句,紧凑占空间小,IO效率高,一些内置函数比如取当前时间在主从之间表现不一致,需要保证 Repeatable Read 及以上隔离级别。参考链接http://mysql.taobao.org/monthly/2018/08/04/
    Row:记录下每一行数据修改的细节,修改成什么值,需要更多的空间,确保主从之间数据一致,可以将隔离级别改成 Read Commited,获得更大的并发性。
    Mixed:混合上面两种

  • 13binlog 刷盘机制
    默认是缓冲写,在宕机时可能造成数据丢失,可以通过修改 sync_binlog = 1,表示不使用操作系统的缓冲,直接使用同步写磁盘的方式记录 binlog。事务提交之前 binlog 已经记录了此时发生宕机,重启的时候事务会被回滚,如果 binlog 里记录了日志就会有问题,可以通过 innodb_support_xa 来解决,会用到 二阶段提交。

  • 14 innodb是如何存储数据的
    reference

  • 来源群友分享

  • 加群请加wx: tutengdihuang

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值