读书笔记不排版格式、读到哪、记到哪、后期系统整理知识结构。
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
(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