首页 > 数据库技术 > 详细

mysql技术内幕读书笔记

时间:2018-12-29 00:35:13      阅读:336      评论:0      收藏:0      [点我收藏+]

读书笔记不排版格式、读到哪、记到哪、后期系统整理知识结构。 

1、innoDB体系架构图

技术分享图片

图解

(1)innodb存储有多个内存块、组成内存池

(2)内存池负责:维护可访问数据结构、缓存数据

(2)后台线程负责刷新缓存、修改磁盘数据、保证异常恢复

 

2、后台线程

innodb是多线程模型、不同后台线程,任务不同。

(1)Master Thread

  • 主后台线程、负责根据checkpoint 机制将缓存池数据异步刷新到磁盘、保证数据一致性。

  (2)IO Thread

  •  Innodb大量使用AIO(async IO)处理请求、提高数据库性能。
  • lOThread类型有 write 、read 、insert buffer 、 log 四种 。
  • 使用innodb_read_io_threads 和 innodb_write_io_threads 配置参数可以设置read io 和 write io 的数量
  • show engine innodb status 命令 观察IO Thread
  • 技术分享图片

     

  • 可以发现读线程id 总数小于写线程id ,且默认各自数量为4

  (3)Purge Thread

  • 用于回收undo页

(4)Page Cleaner Thread

  • 刷新脏页、减轻Master Thread负担、减少 read Thread 阻塞

3、内存

(1)缓冲池

  • innodb存储引擎是基于磁盘存储的(Disk-base Database)、由于cpu 与磁盘的性能差距大 ,使用缓存提高性能,缓存池其实就是一块内存区域
  • 数据库读取页操作,先读到缓存池 、这个过程叫 将页“FIX”到缓存池、下次先从缓存中取
  • 数据库修改页操作,先修改缓存池中的页 ,再以一定频率,刷新到磁盘,这种刷新机制叫CheckPoint
  • innodb 缓存池通过 innodb_buffer_pool_size 参数来设置
  • 缓存池中的数据页类型有: 索引页 、数据页 、undo页 、插入缓存(insert buffer) 、自适应哈希索引(adaptive hash index)、 锁信息(lock info)等,但主要是索引页 、数据页
  • innodb1.0版本之后,允许有多个缓存池实例、每个页根据hash值平均分配到不同缓存池、减少了数据库内部资源的竞争,增加并发能力。可以通过innodb_buffer_pool_instances 配置缓存池实例数,默认为1
  • 可以通过show engine innodb status 查看buffer pool信息

(2)缓存池管理

  • 通常数据库中的缓存池是通过LRU(latest recent userd ,最近最少最少使用)算法管理的,频繁使用的放在LRU list 前端、不频繁使用的放在尾端、缓冲池满的时候优先释放尾端的页
  • innodb存储中,缓冲池 页的默认大小是16k ,也使用LRU算法对缓存池进行管理、但是做了一点优化
  • innodb存储引擎中,LRU列表加入了midpoint 位置。新都的页不是放在LRU List 首部 ,而是放在midpoint 位置,这种方式叫 midpoint insertion startegy
  • midpoint 的位置可以通过参数innodb_old_blocks_pct 配置、值百分比的数字部分,如37 ,表示LRU列表尾端37%的位置
  • 在innodb存储引擎中,将midpoint 之后的LRU list 称为 old list ,之前称为new list
  • 优化原因: 由于索引或数据扫描操作,会访问到许多页、甚至全部页、这些页并不是热点数据、若插入到LRU list 首端、可能会把尾端的热点数据刷出
  • 当缓存数据超过midpoint 点的时候,可以通过设置innob_old_blocks_time 来指定等待多长时间后才将数据加入到 LRU list 的new 端,也是为了避免热点数据被刷出
  • 总结innodb 在LRU 算法加了两个可配置的优化点 :midport  、过点等待,来避免热点数据被刷出
  • LRU list 是用来管例已读取的页的,数据库实例刚启动的时候,LRU list 是空的。此时Free list 中有许多空白页
  • 当读取页时,先到Free list 中看是否有空白页,有将其从FreeList中删除、放入LRU list中,没有的话,淘汰LRU列末尾的页,将列分配给新的页
  • Buffer pool size >  Free buffer +  Database pages , 因为缓存池的页还要分配给 哈希索引、锁信息 、insert Buffer 等页,这部分页不需要LRU算法管理  
  • 技术分享图片

     

  • page make young: 当页从LRUlist的old部分 加入到new部分的过程称之为 page make young, engine status 中的page make young 显示了页从old 移动到 new 发生的次数
  • page not make young: 因为innodb_old_blocks_time 的设置导致的页没有从old 移到new 的描述。如果没有设置innodb_old_blocks_times则为0
  • youngs/s  、non-young/s 表示这两种操作没秒发生的次数
  • 技术分享图片

     

  • buffer pool hit rate : 表示缓存池的命中率,100% 非常好、低于95% 检查是否由于全表扫描导致LRU污染
  • 执行show engine innodb status : 显示的是过去一个时间段innodb 的状态
  • 技术分享图片

     

  • 缓冲池的状态还存在了information_schema.INNODB_BUFFER_POOL_STATS
  • 技术分享图片

     

  • information_schema.INNODB_BUFFER_PAGE_LRU中由于存储 LRU列表中每个页的具体信息
  • innodb引擎支持压缩页的功能,将原来每个页的16k 压缩到1 、2、4、8 k 。对于非16K的page ,是通过unzip_LRU list 管理的
  • 技术分享图片

     

  • 对于压缩页 ,由于每个表的压缩比例不同,各个页的大小不同,unzip 如何管理?以向缓冲池申请4k的大小为例
  • (1)先向4k的unzip_LRU 中申请空白页、有直接使用
  • (2)没有,向8k的unzip_LRU 中申请,有,将其分割成2个4k的页存放到4k 的unzip_LRU list中,使用其中一个
  • information_schema。INNODB_BUFFER_PAGE_LRU保存upzip_LRU  list中page的信息,注意和LRU list page 信息保存在同一张表
  • LRU中的页被修改之后就是脏页了,即缓冲池与磁盘数据不一致了
  • 脏页存在与FLUSH list中,等待master Thread 通过check point 机制刷新到数据库
  • 脏页即存在于FLUSH list中,也存在与LRU list中 ,LRU 列表用于缓冲数据,方便读取、flust list 用于刷新 ,互不影响
  • 技术分享图片

     

  • 脏页既然存在与LRU list中,就可以在information_schema.INNODB_BUFFER_PAGE_LRU 中查到,但是要加入oldest_modirication>0的条件
  • -------------------------------------------
  • innodb内存区除了缓冲池外,还有重做日志缓存(redo log buffer),用于存储重做日志信息。master Thread将其刷新到重做日志文件
  • 重做日志缓存不需要设置很大,一般一秒就会刷新一次 ,默认为8M
  • 用户需要保证每秒产生的事物量在这个缓冲内即可
  • 缓存的大小有innodb_log_buffer_size 控制
  • 刷新时机: 事务提交、master 每秒跑批刷新、容量小于1/2刷新
  • -----------------------
  • 额外的内存池: 用于缓存 每个缓存池的buffercontrol bolck 缓存控制对象,该对象存了LRU、锁 、等待等信息

 

3、checkpoint 技术

(1)check point 是用于master thread 将缓冲池中的脏数据、缓冲到磁盘中的

(2)若每次执行修改,就直接跟新磁盘,开销大;

(3)但是如果不及时刷新,就可能到时宕机时,缓存中的数据丢失

(3)为解决上述数据丢失问题,事物数据库普遍使用Write Ahead Log 策略, 当事物提交时,先写重做日志,再修改页

(5)当出现上述情况、通过重做日志,恢复数据

(6)这就是数据库ACID 中D ,durability 持久性的要求,即事务提交,对数据库所作的更改便持久的保存在数据库之中,不可回滚

-------------------------------

(7)check point(检查点):三个目标,缩短数据恢复时间、缓存池不够时刷新脏页 、 重做日志不可用(覆盖到临界点)刷新脏页

(8)当数据库宕机时,不需要重做所有日志、checkpoint之前的页都已经刷新了、只需对checkpoint 后的重做日志进行数据恢复 、缩短了恢复时间、实现第一个目标

(9)当缓冲池不够用时候、根据LRU算法会刷出最近不常用的页,若此页是脏页、那么就强制刷新、并建立checkpoint

(10)重做日志覆盖到临界点: 数据库对重做日志的设计时循环使用的。后面产生的重做日志会去按最先顺序去覆盖前面产生的重做日志,覆盖之前会判断该部分重做日志在缓存池中对应的页是否已经刷新,即该部分日志是否还有用、如果没有直接覆盖,如果到了有用的临界点,强制在该点产生checkpoint,并刷新缓存到当前checkpoint位置

 

----------------------------------------------------

 (11)innodb使用LSN (Log Sequence Number) 来标记版本,重做日志也有lsn版本 ,lsn 是8位数字

技术分享图片

 

 -------------------------------------------------------------------------------------------------

(12)check point 有两种类型 Sharp Checkpoint  、 Fuzzy CheckPoint

(13)sharp checkpoint 数据库关闭时刷新所有脏数据,这是默认的工作方式,即innodb_fast_shutdown=1

(14)在数据库运行时使用Fuzzy checkpoint 刷新脏页,只刷新部分脏页

-----------------------------------------------------------

(15)innodb 存储引擎中可以发生以下四种check point: master thread checkpoint 、flush_lru_list checkpoint 、async/sync flush checkpoint 、dirty page too much checkpoint

  (16) master thread checkpoint: master thread 以异步方式、每秒或每10s 刷新磁盘 、异步不会阻塞

(17)flush_lru_list checkpoint: 缓冲池不够用,刷出LRU list 末端的页,且该页是脏页、则强制刷新,建立checkpoint

  (18)  Async/Sync Flush checkpoint : 重做日志不可用时的强制checkpoint .

checkpoint_age = redolsn - checkpoint_lsn

async_water_make = 75% * total_redo_log_file_size

sync_water_mark = 90% * total_redo_log_file_size

async_water_mark<checkpoint_age<sync_warter_mark =>async flush checkpoint

checkpoint_age>sync_water_mark => sync flush checkpoint

(19) dirty page too much : 当缓冲池中脏页达到一定数量就强制checkpoint 、可以通过innodb_max_dirty_pages_pct配置比值(不带百分号)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

mysql技术内幕读书笔记

原文:https://www.cnblogs.com/dehigher/p/10188137.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!