您的位置:首页 > 数据库 > MySQL

mysql-innodb存储引擎读书笔记(一)

2018-01-11 16:23 127 查看
连接mysql时使用unix套接字只能在mysql客户端和数据库实例在同一台服务器上

innnodb体系架构:
后台线程:刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据;将已修改的数据文件刷新到磁盘
默认情况下,innodb有7个后台线程——4个IO thread,1个master thread,1个lock监控线程,1个错误监控线程(IO thread的数量由配置文件innodb_file_io_threads参数控制)



说明:4个IO线程分别是insert buffer thread、log thread、read thread、write thread
现在默认不在用innodb_file_io_thread参数 ,而是分别用 innodb_read_io_threads和innodb_write_io_threads参数。

内存
存储引擎内存组成部分:缓冲池(buffer pool)、重做日志缓冲池(redo log buffer)、额外的内存池(addtional memory pool)由配置文件的参数 innodb_buffer_pool_size和innodb_log_buffer_size的大小确定。
innodb存储引擎的工作方式:将数据库中文件按页(16K)读取到缓冲池,然后按照最近最少使用(LRU)算法保留缓冲池中缓存数据。如果数据文件需要修改,总是首先修改在缓冲池中的页(发生修改后,该页即为脏页),然后按照一定的频率将缓冲池的脏页刷新(flush)到文件

可以通过show engine innodb status(显示的是过去某个时间范围内innodb存储引擎的状态)可以查看innodb_buffer_pool的具体情况



说明:buffer pool size表明有多少个缓冲帧(buffer frame),free buffers 表示当前空闲的缓冲帧,database pages表示已经使用的缓冲帧,modified db pages 表示脏页的数量。(每个缓冲帧为16K)
缓冲池中缓存的数据页类型有:索引页、数据页、undo页、插入缓冲(insert buffer)、自适应哈希索引(adaptive hash index)、innodb存储的锁信息(lock info)、数据字典信息(data dictionary)
innodb存储引擎中内存的结构情况



说明:
日志缓冲(log buffer):将重做日志信息先放入该缓冲区,然后按一定频率将其刷新到重做日志文件。
额外内存池(innodb_additional_mem_pool_size):对一些数据结构本身分配内存,从该内存池申请,当该区域的内存不够时会从缓冲池申请。
缓冲池:每个缓冲池中的帧缓冲还有对应的缓冲控制对象(buffer control block),这些对象记录了如LRU、锁、等待等方面的信息。

master thread
master thread的线程优先级别最高。
每一秒的操作包括:
日志缓冲刷新到磁盘,即使这个事务还没有提交(总是)
合并插入缓冲(可能)
至多刷新100个innodb的缓冲池中的脏页到磁盘(可能)
如果当前没有用户活动,切换到background loop(可能)
即使某个事物还没有提交,innodb存储引擎仍然会每秒将重做日志缓冲中的内容刷新到重做日志(解释为什么再大的事务commit的时间很快)
合并插入缓冲的发生取决于当前一秒内的IO压力,很小(io次数是否小于5次)则执行合并插入缓冲操作
innodb通过判断当前缓冲池中脏页的比例(buf_get_modified_ratio_pct)是否超过了配置文件中innodb_max_dirty_pages_pct(默认为90%)
background loop会执行如下操作:
删除无用的undo页(总是)
合并20个插入缓冲(总是)
跳回到主循环(总是)
不断刷新100个页,直到符合条件

每10秒的操作:
刷新100个脏页到磁盘(可能)
合并至多5个插入缓冲(总是)
将日志缓冲刷新到磁盘(总是)
删除无用的undo页(总是)
刷新100个或者10脏页到磁盘(总是)
产生一个检查点(总是)
将100个脏页刷新到磁盘取决于过去10秒之内磁盘的IO操作是否小于200次
这个阶段总会进行合并插入缓冲操作
innodb会执行一步full purge操作,即删除无用的undo页
innodb检查点称为模糊检查点(fuzzy checkpoint),在该检查点将最老日志序列号(oldest LSN)的页写入磁盘

用show engine innodb status 可以查看当前master thread的状态信息



说明:主循环了45次,每秒sleep了45次,10秒一次的执行了4次,符合1:10,background loop执行了6次,flush loop执行了6次说明该服务器压力很小。



说明:主循环了2188次,但是循环中每一秒sleep的操作只运行了1537次。当压力大时,并不能认为1_seconds和sleeps的值总是相等。通过两者之间的差值可以反应数据库的负载压力

innodb_io_capacity默认值为200,对于刷新到磁盘的数量,会按照innodb_io_capacity的百分比来刷新相对数量的页。规则如下:
在合并插入缓冲中,合并插入缓冲的数量为innodb_io_capacity数值的5%
在从缓冲区刷新脏页时,刷新脏页的数量为innodb_io_capacity
innodb_max_dirty_pages_pct默认值为75性能最好。这样可以加快刷新脏页的频率,也能保证磁盘IO的负载

innodb_adaptive_flushing(自适应刷新):影响每一秒刷新脏页的数量。
规则:通过buf_flush_get_desired_flush_rate(实际上是通过判断产生重做日志的速度)的函数来判断需要刷新脏页合适的数量。所以,当脏页的比例小于Innodb_max_dirty_pages_pct时也可以刷新脏页。

innodb关键特性:插入缓冲、两次写(double write)、自适应哈希索引(adaptive hash index)

插入缓冲(提高性能):inset buffer和数据页一样都是物理页的一个组成部分
原理:判断插入的非聚集索引页是否在缓冲池中,如果在,则直接插入;如果不在,则先放入一个插入缓冲中,然后再以一定的频率执行插入缓冲和非聚集索引页子节点的合并操作。
插入缓冲的使用条件:索引是辅助索引;索引不是唯一的;
可以通过show engine innodb status查看插入缓冲的信息



说明:
seq size显示当前插入缓冲的大小为11366*16kb;free list len表示空闲列表的长度;size代表已经合并记录页的数量
inserts代表插入的记录数;merged recs代表合并的页的数量;merges代表合并的次数。merges:merges recs大约为3:1代表插入缓冲对非聚集索引页的IO请求大约降低了3倍
插入缓冲存在的问题:当写密集的情况下,插入缓冲会占用过多的缓冲池的内存,默认情况下可以占用1/2的缓冲池的内存。通过修改IBUF_POOL_SIZE_PER_MAX_SIZE可以对插入缓冲的大小进行控制。如改为3即为1/3.

两次写(数据的可靠)(double write)
部分写失效:当数据库宕机时,数据库正在写一个页面,且这个页面只写了一部分(比如16k的页,只写了4K)
重做日志中记录的是对页的物理操作,如果页本身已经损坏,再对其进行重做是没有意义的,意思就是我们在应用重做日志前,需要一个页的副本
double write:当写入失效时,先通过页的副本来还原该页,再进行重做
doublewrite体系架构:



说明:
doublewrite由两部分组成:1.内存中的doublewrite buffer,大小为2MB;2.物理磁盘上共享表空间中连续的128个页,即2个区(extent),大小同样为2MB;
原理:当缓存中的脏页刷新时,通过memcpy函数将脏页先拷贝到内存中的doublewrite buffer,之后通过doublewrite buffer再分两次,每次写入1MB到共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘。
注:写入doublewrite是顺序写(因为doublewrite页是连续的),但是将doublewrite buffer中的页写入各个表空间时的写入则为离散的。
可以通过show global status like 'innodb_dblwr%' 来查看运行情况



innodb_dblwr_pages_written(一共写的页)与innodb_dblwr_writes(实际写入次数)的比例基本为64:1,远小于这比例则表示系统的写入压力并不是很高。
参数skip_innodb_doublewrite可以禁止使用两次写功能

自适应哈希索引
自适应哈希索引:innodb通过监控表上索引的查找,如果观察到建立哈希索引可以带来速度的提升,则建立hash索引。
自适应哈希索引通过缓冲池的B+树构造而来
通过show engine innodb status可以看到当前自适应哈希索引的使用状态



说明:包括自适应哈希的大小、使用情况、每秒使用自适应哈希索引搜索的情况
注意:哈希索引只能用来搜索等值的查询
可以通过innodb_adaptive_hash_index参数来禁用或者启动自适应哈希索引

译者介绍:家华,从事mysqlDBA的工作,记录自己对mysql的一些总结
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息