从MySQL5.5 开始InnoDB是默认的存储引擎。
MySQL5.6版本中InnoDB的版本为 1.2.X版本。
InnoDB 使用了一个大的内存池,这些内存包含东西:?图2-2todo
多个内部数据结构: 线程要是的。
缓存磁盘上的数据: 方便快速读取。将要写入磁盘上的新数据缓存: 缓冲池(innodb_buffer_pool)
重做日志 redo log缓冲;(redo log_buffer)
InnoDB 是多线程模型,都有哪些线程?
- Master Thread 主要功能: 负责将缓冲池中的数据 异步刷新到磁盘。 保证数据的一致性。这些数据包括: 脏页的刷新;insert buffer 合并插入缓冲;undo页的回收等。
- IO Thread
包括 write 默认4个 由参数innodb_read_io_threads
read 默认4个 由参数innodb_write_io_threads
insert buffer
log io
- purge thread
主要功能 undo页的回收;使用参数 innodb_purge_threads 调整线程的个数如:
[mysqld]
innodb_purge_threads =4; //开启4个线程,默认可能是一个。
- Page Cleaner Thread : 主要功能: 将之前版本中脏数据刷新放到单独的线程中。
缓冲池
相关参数:innodb_buffer_pool_size 可以设置缓冲池的大小。
缓冲池中缓存,有:
索引页 (index page);
数据页(data page) ;
插入缓冲(insert buffer); //不需要LRU算法管理
锁信息(lock info) ; //不需要LRU算法管理
自适应哈希索引; //不需要LRU算法管理
数据字典信息;
参数: innodb_buffer_pool_instances = 2 //代表启动多个缓冲池实例。每个页根据哈希值平均分配到不同缓冲池实例中,增加数据库的并发处理能力。默认值 1
怎么查看缓冲池?
show engine innodb status;
或查看information_schema 架构下表 innodb_buffer_pool_stats
相关的表: innodb_buffer_page_lru 可查看每个LRU列表中每个页的具体信息。
缓冲池中 怎么管理 页(感觉是 主要针对data page 中的页)?
使用LRU算法 来管理; 频繁访问的页(16k) 放在列表前端, 而最少使用的页在LRU列表的尾端。;InnoDB 还加入了midpoint ;默认在LRU列表长长度的5/8处。; midpoint前 称为new 列表; midpoint 后称为old列表。 新读到的页放到midpoint位置。
相关参数 innodb_old_blocks_pct
当数据库刚启动时,LRU列表是空的。 这时页都存放在Free列表中。
当LRU列表的old部分加入到new部分时, 称发生的操作为 page made young
show engine innoDB status;
中行 Database pages 就是LRU列表。
行:buffer pool hit rate 表示缓冲池的命中率,通常该值不应该小于95%
行: LRU len 1539, unzip_LRU len: 156; //LRU中页包含了unzip_LRU列表中的页。
行: Modified db pages 24673; //显示了脏页面的数量及脏页的类型。
InnoDB支持压缩页, 是通过unzip_LRU列表进行管理的; unzip_LRU 对不同压缩页大小页管理 通过伙伴算法进行内存的分配。
脏页 dirty page : 在LRU列表中的页被修改后称为脏页。 脏页既存在于LRU列表中也存在于flush列表中。LRU列表来管理缓冲池中页的可用性,Flush列表用来管理将页刷新回磁盘,二者互不影响。
重做日志缓冲 redo log buffer
InnoDB 首先将重做日志信息先放到这个缓冲区,然后按一定频率将其刷新到重做日志文件。
参数innodb_logo_buffer_size 控制大小 默认为8M
有哪些情况下 会将重做日志缓冲中的内容刷新到磁盘的重做日志文件中?
- Master Thread 每一秒将重做日志缓存 刷新到 日志文件中。
- 每个事务提交时会将重做日志缓冲刷新到重做日志文件中。
- 当重做日志缓冲池剩余空间小于1/2 时。
额外的内存池 innodb_additional_mem_pool_size
write ahead log 策略: 即当事务提交时,先重做日志,再修改页。
checkpoint技术 是 当满足指定的条件时,将脏页刷新到磁盘。 每个页都有LSN,重做日志也有LSN; (Log Sequence Number);
Master Thread 工作方式
Master Thread 具有最高的线程优先级别。其内部由多个循环(loop)组成:
主循环(loop); 后台循环(backgroup loop) ; 刷新循环(flush loop); 暂停循环(suspend loop)。
主循环:(loop)
每秒一次或每秒10秒一次
每一秒操作包括:
日志缓冲刷新到磁盘,即使这个事务还没有提交(总是)
如果满足;前一秒发生的IO次数小于5次, 合并插入缓冲(可能);
至多刷新100个InnoDB的缓冲池中的脏页到磁盘(可能) 脏页的比例 > 75% //1.2.x 交给单独的线程
//脏页的比例 和参数 innodb_max_dirty_pages_pct 默认 75 (75%)这个参数决定刷不刷新问题。
// 参数 innodb_adaptive_flushing 该值影响每秒刷新脏页的数量。
如果当前没有用户活动,则切换到backgroup loop(可能) //
每十秒的操作,包括如下内容:
刷新100个脏页到磁盘(可能的情况)//1.2.x 交给单独的线程
//100个 这个可由参数 innodb_io_capacity //脏页数量; 默认 200
合并至多5个插入缓冲(总是); // 5 和 innodb_io_capacity 的 5%
将日志缓冲刷新到磁盘(总是);
删除无用的undo页(总是); //删除undo页的 数量 和 参数: innodb_purge_batch_size; 默认20
刷新 100个 或10个脏页到磁盘(总是); //1.2.x 交给单独的线程
backgroup loop
删除无用的Undo页(总是)
合并20个插入缓冲(总是)
跳回到主循环(总是)
不断刷新100个页直到符合条件(可能,跳转到 flush loop中完成)
InnoDB 关键特性:
插入缓冲 (insert buffer);
两次写(Double write)
自适应哈希索引(Adaptive Hash Index)
异步IO (Async IO)
刷新领接页(Flush Neighbor Page)
什么操作 或是谁 用到 Insert Buffer ?
索引是辅助索引(secondary index); 且 索引不是唯一的(unique)的。
1.2.x 升级为 Change Buffer
大小 参数 innodb_change_buffer_max_size 默认是 25 ,含义是最多使用1/4的缓冲内存空间。
包括 insert Buffer; Delete Buffer; Purge buffer;
Insert Buffer 的数据结构是一棵B+树。 全局只有一棵 B+树, 负责对所有表的辅助索引进行Insert Buffer.
这颗B+树存放在共享表空间中。默认就是ibdata1;
什么时候 Insert Buffer中的记录合并merge 到真正的辅助索引中呢?
- 辅助索引页被读取到缓存池时;
- Insert Buffer Bitmap 页追踪到该辅助索引页已经无可用空间
- master thread.
两次写:
带给InnoDB存储引擎的是数据页的可靠性。
重做日志中记录的是对页的物理操作,如偏移量 800, 写记录。如果这个页已经发生了损坏,在对其进行重做没有意义。
doublewrite 由两部分组成,一部分是内存中的doublewrite buffer, 大小为2M,另一部分是物理磁盘上共享空间中连续的128页,即2两个区(extent)。
图 2-5 todo;
如果操作系统在将页写入磁盘的过程中发生了崩溃,在恢复的过程中? ,InnoDB存储引擎可以从共享表空间中的doublewrite 中找到该页的一个副本,
将其复制到表空间文件,再应用重做日志。
自适应哈希:Adaptive Hash Index, AHI).
InnoDB 存储引擎会自动根据访问的频率和模式来自动的为某些热点页建立 哈希索引。
如: 以该模式访问了100次; 或 通过该模式访问了N次 ,N= 页中记录* 1/16;
访问模式一致 指的是查询的条件一样。
哈希索引只能用来搜索等值的查询。 如: select * from table where index_col=‘xxx’,
参数: innodb_adaptive_hash_index 默认开启。
异步IO
并且可以IO Merge, 是内核级别的AIO /也称为 Native AIO 。 需要libaio 库的支持。
参数 innodb_use_native_aio 默认ON
在InnoDB 存储引擎中, read ahead 方式的读取都是通过AIO完成, 脏页的刷新 都是AIO 方式
刷新邻接页:
参数: innodb_flush_neighbors 默认ON
启动关闭恢复
参数 innodb_fast_shutdown 默认 1
参数 innodb_force_recovery 默认 0 //表示需要恢复时,进行所有的恢复操作。