• 高并发下MySQL事务以及优化


         MySQL有一个最大的缓冲区  Buffer  Pool(默认大小128M),用来缓存  页 ,将查询到的页放到  Buffer  Pool

        这时有一个  free链表,头节点存储了当前链表的元素个数以及下一个链表在哪里,后续的链表存储 Buffer  Pool里哪些区域是空闲的,当空闲的Buffer  Pool的区域被使用的时候,相应的free链表的节点也被删除

        同时又有一个  lru链表,头节点也是存储了当前链表的元素个数,来将在free链表中删除的节点加入到  lru链表中的头节点后面,使用最近最少使用算法,最近被使用节点也会放到头节点后面,

        当再一次更新中,Buffer  Pool 中所有的数据全部换掉, 这一行为被称作换血

        为了避免换血这种情况发生,MySQL对   lru  链表进行了升级,前 5/8 的部分用来存储热数据,也就是经常访问的数据,后 3/8 的部分用来存储冷数据,也就是不是经常被访问的数据,而且冷数据也可以升级成为热数据,当一个冷数据被连续访问,而且两次访问时间相差大于1s,t2   -   t1  >  1s,避免一个SQL语句连续访问多次冷数据,这时候这页冷数据就升级成为了热数据,同时最后一条热数据被淘汰掉成为冷数据。

        前   1/4  的热数据没有必要交换,也就是没必要看谁是最长被访问的数据,因为会造成前面的热数据进行多次没有意义的交换,本质是:这是淘汰的机制,而不是找出最热的机制,没有必要浪费时间

        Buffer  Pool里面肯定有一些页是被修改的,我们称之为脏页,MySQL内置了线程  定时地更新脏页

        类似free链表,当Buffer  Pool中有页被update 更新修改之后,会放在  flush链表头节点后面,之后内置定时更新地线程 会在链表里面找相应的地址来进行更新

                                                         

        对于更新脏页,MySQL有两个 Redo Log日志,专门来存储脏页相关地日志,当两个日志全都存储满了之后或者后台线程定时地   就开始更新脏页进行持久化,这就完成了从随机IO到顺序IO地转变

        但是,有可能在进行事务的时候两个日志满了必须进行持久化,就会让事务滞后,这时我们可以进行对Read Log 的配置,让空间变大或者数量变多。但是同样有弊端,当MySQL因为一些原因挂掉的话,需要依靠  Read Log 日志进行数据的恢复,就回导致打开MySQL的速度变慢

        双写缓冲区————脏页有16kb,但是操作系统每次写只能写入4kb,所以要分4次写入磁盘进行持久化,但是有可能写入了1、2、3次而中途挂掉,最终导致没有一次性写完

        在磁盘里面开辟一个新的空间,让Buffer  Pool中脏页的数据进行持久化写入到这个新开辟的空间中,如果写入成功,就根据这个新数据再写入磁盘中原有的老数据,如果这时候程序挂掉,可以再根据新数据对比老数据进行继续持久化写入,如果没挂掉就成功了。如果在第一次写入的到新开辟的空间的时候中途挂掉,老数据区域可以根据Redo Log 进行持久化写入。

        但是现在有一些的硬盘是支持源自写入的,意味着要么将16kb的数据全部写完,要么16kb数据全部都不写入。

        

                  双写缓冲区示意图

  • 相关阅读:
    操作系统---学习笔记00
    操作系统---学习笔记0
    2015/07/16入园啦!
    1-1 console的用法
    2.3 js基础--DOM
    1.2 js基础
    1.1 js基础
    信息收集(1)
    Android概述
    从一次失败的比赛经历引发的思考
  • 原文地址:https://www.cnblogs.com/2940500426yingxin/p/16019202.html
Copyright © 2020-2023  润新知