🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
![](https://box.kancloud.cn/d57341bb0d28a7b34576b1fe3d667ef5_795x438.png) ![](https://box.kancloud.cn/6a0ab9f0410a8f9c38f03f2b455491f4_955x589.png) 1、缓存池 buffer pool缓存池是InnoDB在内存中开辟的用来缓存表数据和索引数据的区域,一般 可以设置为50%~80%的物理内存大小,通过对经常访问的数据放置到内存当中来加快访 问速度。 Buffer pool以page页的格式组成,页之间组成list列表,并通过LRU算法(最近最少使用算法)对长久不使用的页进行置换。 数据的读写需要经过缓存(缓存在buffer pool 即在内存中) 数据以整页(16K)位单位读取到缓存中 缓存中的数据以LRU策略换出(最少使用策略) IO效率高,性能好 2、Adaptive Hash Index(自适应哈希索引) Adaptive Hash index属性使得InnoDB更像是内存数据库。该属性通过innodb_adapitve_hash_index开启,也可以通过—skip-innodb_adaptive_hash_index参数关闭 InnoDB存储引擎会监控对表上索引的查找,如果观察到建立哈希索引可以带来速度的提升,则建立哈希索引,所以称之为自适应(adaptive) 的。自适应哈希索引通过缓冲池的B+树构造而来,因此建立的速度很快。而且不需要将整个表都建哈希索引,InnoDB存储引擎会自动根据访问的频率和模式 来为某些页建立哈希索引。 哈希(hash)是一种非常快的等值查找方法,在一般情况下这种查找的时间复杂度为O(1),即一般仅需要一次查找就能定位数据。 innodb会监控对表上个索引页的查询。如果观察到建立哈希索引可以带来速度提升,则自动建立哈希索引 AHI,是数据库自动优化的 3、Redo log buffer Redo log buffer是一块用来存放写入redo log文件内容的内存区域,内存的大小由innodb_log_buffer_size参数确定。该buffer的内容会定期刷新到磁盘的redo log文件中。 参数innodb_flush_log_at_trx_commit决定了刷新到文件的方式,参数innodb_flush_log_at_timeout参数决定了刷新的频率。 4、系统表空间 InnoDB的系统表空间用来存放表和索引数据,同时也是doublewriter缓存,change缓存和回滚日志的存储空间,系统表空间是被多个表共享的表空间。 默认情况下,系统表空间只有一个系统数据文件,名为ibdata1。系统数据文件的位置和个数由参数innodb_data_file_path参数决定。 5、Doublewrite缓存 Doublewrite缓存是位于系统表空间的存储区域,用来缓存InnoDB的数据页从innodb buffer pool中flush之后并写入到数据文件之前,所以当操作系统或者数据库进程在数据页写磁盘的过程中崩溃,Innodb可以在doublewrite缓存中找到数据页的备份而用来执行crash恢复。 数据页写入到doublewrite缓存的动作所需要的IO消耗要小于写入到数据文件的消耗,因为此写入操作会以一次大的连续块的方式写入。 doublewrite组成: 内存中的doublewrite buffer,大小2M, 物理磁盘上共享表空间中连续的128个页,即2个区(extend),大小同样为2M。 对缓冲池的脏页进行刷新时,不是直接写磁盘,而是会通过memcpy()函数将脏页先复制到内存中的doublewrite buffer,之后通过doublewrite 再分两次,每次1M顺序地写入共享表空间的物理磁盘上,在这个过程中,因为doublewrite页是连续的,因此这个过程是顺序写的,开销并不是很大。在完成doublewrite页的写入后,再将doublewrite buffer 中的页写入各个 表空间文件中,此时的写入则是离散的。如果操作系统在将页写入磁盘的过程中发生了崩溃,在恢复过程中,innodb可以从共享表空间中的doublewrite中找到该页的一个副本,将其复制到表空间文件,再应用重做日志。 ![](https://box.kancloud.cn/ee9d8f5b06765b67a656d427921002d2_999x627.png) 6、Undo日志 Undo日志是由一系列事务的undo日志记录组成,每一条undo日志记录包含了事务数据回滚的相关原始信息,所以当其它的事务需要查看修改前的原始数据,则会从此undo日志记录中获取。Undo日志存放在回滚段中的undo日志段中。默认情况下回滚段是作为系统表空间的一部分,但也可以有自己独立的undo表空间,通过设置innodb_undo_tablespaces和innodb_undo_directory两个参数。 Innodb支持最大128个回滚段,其中的32个用来服务临时表的相关事务操作,剩下的96个服务非临时表,每个回滚段可以同时支持1023个数据修改事务,也就是总共96K个数据修改事务。 Innodb_undo_logs参数用来设置回滚段的个数。 Undo Log的原理很简单,为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为Undo Log)。然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态 7、File-per-table表空间 File-per-table表空间意味着innodb的数据表不是共享一个系统表空间,而是每个表一个独立的表空间。可以通过设置innodb_file_per_table开启此属性。开启之后每个表数据和索引数据都会默认单独存放在数据文件夹下的.ibd数据文件中。默认是开启的。 show variables like '%per_table%'; set global innodb_file_per_table=off; ###关闭 8、temporary表空间 temporary临时表空间用来存放临时表,默认情况下是在数据文件夹下的ibtmp1数据文件,此数据文件被设置为每次自动增长12MB大小,当然也可以设置innodb_temp_data_file_path来指定临时表空间文件的存放位置。 临时表空间文件在正常的shutdown之后会自动清除,但在crash发生时不会清除,这就需要DBA手动去删除表空间文件或重启服务器。 show variables like '%innodb_temp%'; 如果发现临时表空间数据文件比较大,可以考虑重启MySQL来释放空间大小。 9、redo log redo日志是存在于磁盘上的文件,包括ib_logfile0和ib_logfile1两个文件,常用于在crash恢复发生时将还没来得及写入到数据文件中但已经完成提交的事务在数据库初始化时重新执行一遍。 InnoDB对redo log buffer写入到redo log文件的方式提供了组提交(group commit)的方式,意味着针对一次写磁盘操作可以包含多个事务数据,用此方法提高性能。 为了IO效率,数据库修改的文件都在内存缓存中完成的; 如果宕机了则:应用已经持久化好了的日志文件,读取日志文件中没有被持久化到数据文件里面的记录;将这些记录重新持久化到我们的数据文件中 innodb日志持久化相关参数 innodb_flush_log_at_trx_commit 0:每秒写入并持久化一次(不安全,性能高,无论mysql或服务器宕机,都会丢数据最多1秒的数据) 1:每次commit都持久化(安全,性能低,IO负担重) 2:每次commit都写入内存的内存缓存,每秒再刷新到磁盘(安全,性能折中,mysql宕机数据不会丢失,服务器宕机数据会丢失最多1秒的数据) innodb_flush_log_at_timeout参数决定最多丢失多少秒的数据,默认是1秒