当前位置: 首页 > news >正文

郑州网站建设冫汉狮网络亚网站建设

郑州网站建设冫汉狮网络,亚网站建设,网站开发项目名称,网络课程推广本文主要聊InnoDB内存结构, 先来看下官网Mysql 8.0 InnoDB架构图 MySQL :: MySQL 8.0 Reference Manual :: 17.4 InnoDB Architecture 如上图所示,InnoDB内存主要包含Buffer Pool, Change Buffer, Log Buffer, Adaptive Hash Index Buffer Pool 其实 buffer pool 就是内存中的… 本文主要聊InnoDB内存结构, 先来看下官网Mysql 8.0 InnoDB架构图 MySQL :: MySQL 8.0 Reference Manual :: 17.4 InnoDB Architecture 如上图所示,InnoDB内存主要包含Buffer Pool, Change Buffer, Log Buffer, Adaptive Hash Index Buffer Pool 其实 buffer pool 就是内存中的一块缓冲池用来缓存表和索引的数据。默认80%的物理内存分配给缓冲池。 我们都知道 mysql 的数据最终是存储在磁盘上的但是如果读存数据都直接跟磁盘打交道的话这速度就有点慢了。所以 innodb 自己维护了一个 buffer pool在读取数据的时候会把数据加载到缓冲池中这样下次再获取就不需要从磁盘读了直接访问内存中的 buffer pool 即可。包括修改也是一样直接修改内存中的数据然后到一定时机才会将这些脏数据刷到磁盘上。 其实缓冲池维护的是页数据也就是说即使你只想从磁盘中获取一条数据但是 innodb 也会加载一页的数据到缓冲池中一页默认是 16k。 Buffer Pool 管理 Buffer Pool 中的页有三种状态 空闲页通过空闲页链表Free List管理。  正常页通过LRU链表LRU List管理。  脏页通过LRU链表和脏页链表Flush List管理。缓冲池中被修改过的页与磁盘上的数据页不一致 Free链表 初始化完的buffer pool时所有的页都是空闲页所有空闲的缓冲页对应的控制块信息作为一个节点放到Free链表中。 要注意Free链表是一个个控制块而控制块的信息中有缓存页的地址信息。 在有了free链表之后当需要加载磁盘中的页到buffer pool中时就去free链表中取一个空闲页所对应的控制块信息根据控制块信息中的表空间号、页号找到buffer pool里对应的缓冲页再将数据加载到该缓冲页中随后删掉free链表该控制块信息对应的节点。 Flush链表 修改了buffer pool中缓冲页的数据那么该页和磁盘就不一致了这样的页就称为【脏页】它不是立马刷入到磁盘中而是由后台线程将脏页写入到磁盘。 Flush链表就是为了能知道哪些是脏页而设计的它跟Free链表结构图相似区别在于控制块指向的是脏页地址。 LRU链表 对于频繁访问的数据和很少访问的数据我们对与它的期望是不一样的很少访问的数据希望在某个时机淘汰掉避免占用buffer pool的空间因为缓冲空间大小是有限的。 MySQL设计了根据LRU算法设计了LRU链表来维护和淘汰缓冲页。 LRU 算法简单来说如果用链表来实现将最近命中加载的数据页移在头部未使用的向后偏移直至移除链表。这样的淘汰算法就叫做 LRU 算法但是简单的LRU算法会带来两个问题预读失效、Buffer Pool污染 预读:  当数据页从磁盘加载到 Buffer Pool 中时会把相邻的数据页也提前加载到 Buffer Pool 中这样做的好处就是减少未来可能的磁盘IO。 改进LRU 算法 Buffer Pool的LRU算法中InnoDB 将LRU链表按照5:3的比例分成了young区域和old区域。链表头部的5/8是young区被高频访问数据链表尾部的3/8区域是old区域低频访问数据箭头朝下的是未被访问的数据朝上的是被访问的数据。 这样做的目的是在预读的时候或访问不存在的缓冲页时先加入到 old 区域的头部等 1s后(大部分场景扫描数据之后同一个请求会马上访问这部分数据,之后可能就不访问了)如果该页面再次被访问才会被移动到新生代。 Buffer Pool刷盘 1有一个后台线程会认为数据库空闲时 2数据库缓冲池不够用时执行sql时刚好碰到缓冲池不够用导致的刷盘时 sql执行得等缓存池刷盘完成 3数据库正常关闭时 4redo log写满时下文详解 Change Buffer 在MySQL5.5之前叫插入缓冲(insert buffer)只针对insert做了优化现在对delete和update也有效叫做写缓冲(change buffer)。 它是一种应用在非唯一普通索引页(non-unique secondary index page)不在缓冲池中对页进行了写操作并不会立刻将磁盘页加载到缓冲池而仅仅记录缓冲变更(buffer changes)等未来数据被读取时再将数据合并(merge)恢复到缓冲池中的技术。写缓冲的目的是降低写操作的磁盘IO提升数据库性能。 写入流程 执行两条Insert语句其中左侧的要更新的数据页 Page1 不在Buffer Pool而右侧需要更新的数据页Page2在Buffer Pool缓存中。 数据页Page1: 不在Buffer Pool中的话, 将修改写入Change Buffer最终写入表空间数据页Page2: 在缓存中直接更新, 最终写入数据文件 两次内存一次是修改Buffer Pool的数据页、另一次是Change buffer中记录这个写入操作。 三次磁盘:  一次redo log(合并批量), 一次change buffer落盘, 一次脏页落盘. 三次落盘都是等到落盘条件之后触发。 Merge流程 读Page2的时候很好理解直接从Buffer Pool 中返回 但是读Page1时需把Page1从磁盘读入内存然后将Change Buffer里面的操作日志Merge生成一个正确版本并返回结果。 适用场景:  数据库大部分是非唯一索引, 并且写多读少。 Log Buffer Log Buffer是给 redo log 做缓冲用的。redo log 我们都知道是重做日志用来保证崩溃恢复数据的正确性innodb 写数据时是先写日志再写磁盘数据即 WAL (Write-Ahead Logging)把数据的随机写入转换成日志的顺序写。 即使是顺序写 log 每次都调用 write 或者 fsync 也是有开销的毕竟也是系统调用涉及上下文切换。于是乎搞了个 Log Buffer默认16M 来缓存 redo log 的写入。 刷盘配置 innodb 其实给了个配置即 innodb_flush_log_at_trx_commit 来控制 redo log 写盘时机。 当值为 0提交事务不会刷盘到 redo log需要等每隔一秒的后台线程将 log buffer 写到操作系统的 cache并调用 fsync落盘性能最好但是可能会丢 1s 数据。 当值为 1提交事务会将 log buffer 写到操作系统的 cache并调用 fsync 落盘保证数据正确性能最差这也是默认配置。 当值为 2提交事务会将 log buffer 写到操作系统的 cache但不调用 fsync而是等每隔 1s 调用 fsync 落盘性能折中如果数据库挂了没事如果服务器宕机了会丢 1s 数据。 redo log 每个 InnoDB 存储引擎至少有 1 个重做日志文件组 redo log group每个文件组下至少有 2 个重做日志文件redo log file默认的话是一个 redo log group其中包含 2 个 redo log fileib_logfile0 和 ib_logfile1 。在日志组中每个 redo log file 的大小一致并以循环写入的方式运行。 如下图举例 一组 4 个文件每个文件的大小是 1GB那么总共就有 4GB 的 redo log file 空间。write pos 是当前 redo log 记录的位置随着不断地写入磁盘write pos 也不断地往后移写到 file 3 末尾后就回到 file 0 开头。CheckPoint 是当前要擦除的位置将 Checkpoint 之后的页刷新回磁盘write pos 和 CheckPoint 之间的就是 redo log file 上还空着的部分可以用来记录新的操作。如果 write pos 追上 CheckPoint就表示 redo log file 满了这时候不能再执行新的更新得停下来先把buffer pool中脏页都flush到磁盘把 CheckPoint 推进一下。 crash-safe 上面change buffer提到二级索引更新操作如果 buffer pool中没有更新数据不会从磁盘拉取数据而是直接把变更记录在change buffer。假如数据库挂了更改不是丢了吗  mysql通过redo log 和 binlog来防止机器宕机之后数据丢失问题。 场景一redo log 没有commitbinlog没有fsync数据丢失。 场景二redo log 没有commitbinlog已经fsync重启之后会对比binlog中的trx_id和redo log中的trx_id, 进行commit redo log。 场景三redo log 已经commitbinlog已经fsync从redo log恢复数据。 Adaptive Hash Index 在MySQL运行的过程中如果InnoDB发现有很多寻路很长比如B树层数太多、回表次数多等情况的SQL并且有很多SQL会命中相同的页面Page的话InnoDB会在自己的内存缓冲区Buffer Pool里开辟一块区域建立自适应哈希索引Adaptive Hash IndexAHI以加速查询。 MySQL 5.5 版本开始提供AHI特性并在后续版本持续改进。在最新的8.0.33版本中依然将该特性默认开启。 首先我们来看一下上图中两个InnoDB内部的B树结构左边的primary key主键索引右边是secondary key二级索引。当我们需要找到主键值为5的记录时就需要从主键索引B数的根节点开始一直搜索到叶子找到最下面的左边第二页然后定位到记录5…。而当我们想要查找二级索引键值为35的那条记录的时候就会先搜索左边的二级索引B树然后定位到355这条二级索引记录再通过对应的主键5到左边的主键索引中找到5…这条完整的数据记录。 而如下图所示AHI通过建立主键5到数据所在数据页的hash索引可以直接定位到记录5…所在的数据页也就是左边数第二个数据页。如此在查找记录的时候就省略了从根节点到叶子节点的搜索过程。 如下图所示AHI的主要数据结构是多个哈希表可以看做它是B树索引的hash索引  优势场景读多写少并且是叶节点定位占比多的场景 。 Doublewrite Buffer Doublewrite Buffer翻译成中文双写缓冲区缩写DWB。Doublewrite 是保障 InnoDB 存储引擎操作数据页的可靠性。 我们都知道 innodb 默认一页是 16K而操作系统 Linux 内存页是 4K那么一个 innodb 页对应 4 个系统页。所以 innodb 的一页数据要刷盘等于需要写四个系统页。 如下图所示Buffer Pool中的Page1 对应系统页中的Page1Page2Page3Page4在写Page4的时候出现了断电了则会出现重启后MySQL内Page 1的页物理上对应磁盘上的Page 1、Page 2、Page 3三个页数据完整性被破坏。Redo Log无法修复这类“页数据损坏”的异常修复的前提是“页数据正确”并且Redo日志正常 针对上面出现的情况如何解决这类“页数据损坏”的问题呢很容易想到的方法是能有一个“副本”对原来的页进行还原这个存储“副本”的地方就是Doublewrite Buffer。 如上图所示当有页数据要刷盘时 第1步页数据先memcopy到DWB的内存里 第2步DWB的内存里的数据页会先刷到DWB的磁盘上 第3步DWB的内存里的数据页再刷到数据磁盘存储.ibd文件上 第4步如果出现如上断电场景从DWB FILE中恢复数据盘 备注DWB内存结构由128个页Page构成所以容量只有16KB × 128 2MB。
http://www.dnsts.com.cn/news/102394.html

相关文章:

  • 如何快捷建企业网站vi设计素材
  • 做物流网站计划永久免费补单系统
  • 网站开发多少钱手机网站怎么写
  • 免费网站建设推广服务asp.net 4.0网站开发
  • vue网站开发wordpress视频曹鹏
  • 加快网站收录网站建设步骤完整版
  • 服务器系统搭建网站源码seo查询外链
  • 西安app开发公司排名搜索引擎推广与优化
  • 网络管理系统中故障管理的目标是线上seo关键词优化软件工具
  • 衡阳城乡建设部网站首页网站建设的实训技术总结
  • 建设网站的技术校园招聘网站策划书
  • 免费的建筑设计网站群晖nas建设网站
  • 哈尔滨专业做网站推广怎么推广公众号
  • 邯郸做网站代理html电影网站模板下载工具
  • 诚信网站备案中心外贸流程及详细步骤
  • 福建省住房和城乡建设厅门户网站ueditor 插件 wordpress
  • 界面网站的风格企业网站开发 外文文献
  • 湖南建设网站公司近五年网站开发参考文献
  • 教育网站建设改版网推
  • 手机网站自适应代码wordpress最佳插件
  • 建设执业资格注册中心网站网站搭建类型
  • 网站建设用户调查报告网站建设 碧辉腾乐
  • 做网站定金是多少wordpress付费内容
  • 信息图表设计网站wordpress在线浏览pdf
  • 个人网站开发网站建设措施
  • 厦门seo网站优化云服务器一年多少钱
  • 思维导图在线制作网站珠海门户网站建设费用
  • 商城类网站建设方案网站优秀作品
  • 义马网站建设电话做直播的在相亲网站交友
  • 单一页面网站怎么做惠阳做网站