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

MySql引擎

2020-04-23 10:06 976 查看

已经了解到MySql数据库的"内部"后我们来看看MySql的引擎

在做数据库优化之前首先要了解MySql的引擎有哪些?

查看数据库引擎:支持哪些引擎?
使用

show engines;

查询结果如下图:

可以看出MySql默认的数据库引擎是InnoDB。
查看当前使用引擎 :

show variables like '%storage_engine%';

指定数据库对象的引擎:

create table t1(
id int(4) primary key,
name varchar(10)
)engine=MYISAM;

比较常见的数据库引擎有么区别呢?
InnoDB(默认) :事务优先 (适合高并发操作;行锁)
MyISAM :性能优先 (表锁)
MySql引擎此处不详细说明,仅仅叙述常见的数据库引擎。

关于InnoDB引擎的详解:

如下图是Innodb的架构图

  • 可以看出Innodb数据库引擎有多个内存,这些内存组成了一个内存池。
  • 其次包含多个后台线程,后台线程主要作用是负责刷新内存池中的数据,让内存池中的数据是最新的。或者将内存吃重的数据刷新到文件中(磁盘),同时当数据库发生异常时让数据库恢复到正常状态。

后台线程:

  1. Master Thread
    后台核心线程:将缓冲池中的数据异步到磁盘中,以此保证数据一致性(刷脏页等)。

  2. IO Thread
    InnoDB使用AIO处理IO写请求,能够提高数据库性能。可以使用innodb_read_io_threads和innodb_write_io_threads参数进行设置

show variables like 'innodb_%io_threads';

  1. Purge Thread
    回收已经使用并分配的undo页。

缓存

Inndb引擎会将数据存放到磁盘中,并按照页进行管理。

这样做是为了解决CPU速度和磁盘速度之间的差距使用缓存来提高数据库的性能。

缓存其实就是一个内存,利用内存速度快的特点来提高数据库想能。例如:进行读取操作时会将在磁盘中的数据页放入到缓存中,并返回到客户端。当我们下一次在读取该页时会判断该页是否在内存中,如果在则直接返回。

而对于修改操作,则直接在缓存中直接修改,然后通过CheckPoint的机制刷回新磁盘,对于缓存的大小可以通过配置参数innodb_buffer_poll_size来设置

下图为Innodb的内存对象
你已经知道缓存对象中放入很多类型的页,那么他们是怎么被管理的呢?
其实数据库的缓存是通过LRU算法来进行管理的。即对于频繁使用的数据页放在最前面,而使用少的数据页放在后面。

当缓存中不能存放新的数据页时而此时新的数据页被加入进来时,则去释放掉LRU尾部的数据页。如下图:

  1. 此时访问内存中的缓存数据R2(假设内存中只能放入这么多缓存数据)。
  2. R2被放置于缓存表头部
  3. 访问不在缓存表中的数据页Rx,删除缓存表尾部Rn,并将Rx放置于缓存表头部

注意:Innodb的LRU算法是通过链表实现的

其实这样做有一定缺陷,比如我要想对一个数据量比较大的表进行全表扫描,而这个表不会被经常访问到,此时缓存会被这个表放满,而以前所有的数据页都会被清除。此时就会影响到内存的命中率。导致磁盘压力增大,影响sql语句的执行速度。

针对以上问题Innodb对这个算法进行改进:

首先将LRU链表通过midpoint将链表分成两个部分,如果读取到新的页则将新页放入到midpoint位置,而不是直接放入到LRU链表首部。默认配置下midpoint在链表的5/8处。将midpoint之后的数据称为“old区域”,之前的数据称为“new区域 ”(可以把new列表中的数据看成比较热点的数据)。

优化后的LRU流程如下:

  1. 访问R2将R2放入LRU链表头部
  2. 访问不存在于链表中的数据页(此时内存已经满了),将位于old区域的Rn移除,并在midpoint处放置新的数据页Rx。
  3. 在old区域的数据页,每次访问的时候都要进行下面的判断:
    (1)若这个数据页在LRU中存在超过1秒,则移动到链表头部
    (2)若这个数据页在LRU中存在的时间小于1秒,位置不变。

这个1秒的时间是由参数innodb_old_blocks_times控制的。可以自己设定(默认是1秒)

set global innodb_old_block_time=1000;

重做缓冲日志

重做缓冲日志(redo log buffer)。Innodb引擎先将重做日志放入到重做缓冲日志中,然后定期将重做缓存中的日志放入到重做日志中。重做缓存日志大小由innodb_log_buffer_size决定

show variables like 'innodb_log_buffer_size';
  • 点赞 2
  • 收藏
  • 分享
  • 文章举报
不正经的“常春藤” 发布了2 篇原创文章 · 获赞 2 · 访问量 433 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: