mysql内存数据淘汰机制和大查询会不会把内存打爆?

首先我们说一下大查询会不会把内存打爆?

比如说主机内存有5g,但是我们一个大查询的数据有10g,这样会不会把内存打爆呢?

答案:不会

为什么?

因为mysql读取数据是采取边读边发的策略

select * from t1

这条语句的流程是这样的

1.读取数据放入net_buffer中,net_buffer大小是由net_buffer_length控制

2.net_buffer放满了以后,调用网络栈发送数据到客户端

3.如果发送成功就清空net_buffer,继续读取数据放入net_buffer中

4.如果发送函数返回EAGAIN或者WSAEWOULDBLOCK就表示本地网络栈满了,这时候就进入等待,知道网络栈重新可写,再继续发送。

根据这个流程来看,读取数据的时候占用的内存最多也就是net_buffer的大小。

InnoDB内存(buffer pool)管理

我们都知道mysql查询数据是先看内存中有没有数据,如果没有就从磁盘中读出来,然后在读入内存

所以说bufferpool对查询有加速效果,加速效果依赖于一个指标也就是内存命中率,如果命中率能达到100%那是最好的

通过

show engine innodb status

可以查看命中率

innodb buffer pool的大小是由参数innodb_buffer_pool_size控制的,一般设置为可用物理内存的60%-80%

内存淘汰

既然内存是一块固定大小的,那么存放在内存里的数据就肯定有的会被淘汰

下面是一个lur算法的基本模型

innodb管理bufferpool的lru算法是基于链表实现的

state1:我们要查询p3的数据,由于p3是在内存中的,那么久直接把p3移动到链表头部,

也就是对应图中state2的状态

state3中由于我们查询的px数据不是在px中,那么就从磁盘中查询出px的数据放入链表头部,

但是由于内存满了,所以

就会把pm的数据从链表尾部淘汰掉,从现象上来看就是最久没有被访问都的数据会被淘汰

这种算法对于mysql来说有什么问题??

如果我们对一个冷数据表进行全表扫描,比如说日志表,这些不是正常用户访问的表,

那么在bufferpool中就会大量存在这些数据的表,那么就会导致用户正常访问存放的业务数据会被淘汰掉,

就会导致大量数据需要重新读磁盘放入内存,这样性能就会大大降低

mysql肯定不会允许这种情况发生的,所以它基于上面的lru算法做了改进

下图就是改进后的模型

innodb把整个内存的前八分之五记为young区域,后八分之三记为old区域,

我们看上图state1中由于我们访问的p3是在young区域,那么就把p3移动到链表头部

但是如果我们访问的数据如果是在old区域,比如说我们访问了px,这个时候会做个判断

如果px在内存中存活时间超过1秒,就会把它移动到young区域的链表头部,否则位置不动

这个1秒是由参数

innodb_old_blocks_time控制的,默认值是1000,单位毫秒

这样我们在看扫描全表的步骤

扫描过程中被访问的数据页会被放在old区域

一个数据页有多条记录会被访问,所以这数据页会被多次访问到,但是由于是顺序扫描,

这个数据页第一次被访问和最后一次被访问的时间间隔不会超过一秒,所以就会一直在old区域

在继续扫描后面的数据页,之前的这个数据页也不会被访问到,因此就会一直在old区域,也就很快就会被淘汰掉了

可以看到这个策略的最大收益,就是在扫描的过程中,虽然也用到了bufferpool,

但是不会对young区域造成影响,也就保证了bufferpool响应业务的内存命中率

原文地址:https://www.cnblogs.com/sjks/p/10855929.html

时间: 2024-10-09 05:36:27

mysql内存数据淘汰机制和大查询会不会把内存打爆?的相关文章

redis数据淘汰机制

一.当读取一个1.5G的文件写入redis时候,机器资源不够,被系统杀掉进程,实验数据上限作罢. redis string理论支持1GB 二.场景:redis 2.6以上版本已经废弃了vm功能,配置文件已关闭redis持久化功能 当reids占用内存大于分配的内存的时候. 1.volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰 redis并不是保证取得所有数据集中最近最少使用的键值对,而只是随机挑选的几个键值对中的, 当内存达到限制的时候无法写入非过期时间的数据集2.

mysql更新数据,条件为实时查询出来的数据

--将更新条件保存到临时表里 CREATE TABLE tmp3 AS (SELECT username FROM oa_user WHERE username NOT IN (SELECT username FROM nst_t_account)); --更新表数据,条件从临时表里取 UPDATE oa_user SET usr_update=NOW() WHERE username IN (SELECT username FROM tmp3); --删除临时表 DROP TABLE tmp3

Redis内存淘汰机制

转自:https://my.oschina.net/andylucc/blog/741965 摘要 Redis是一款优秀的.开源的内存数据库,我在阅读Redis源码实现的过程中,时时刻刻能感受到Redis作者为更好地使用内存而费尽各种心思,例如最明显的是对于同一种数据结构在不同应用场景下提供了基于不同底层编码的实现(如压缩列表.跳跃表等).今天我们暂时放下对Redis不同数据结构的探讨,来一起看看Redis提供的另一种机制——内存淘汰机制. 探初衷 Redis内存淘汰指的是用户存储的一些键被可以

Redis系列--内存淘汰机制(含单机版内存优化建议)

https://blog.csdn.net/Jack__Frost/article/details/72478400?locationNum=13&fps=1 每台redis的服务器的内存都是有限的,而且也不是所有的内存都用来存储信息.而且redis的实现并没有在内存这块做太多的优化,所以实现者为了防止内存过于饱和,采取了一些措施来管控内存. 文章结构:(1)内存策略:(2)内存释放机制原理:(3)项目中如何合理应用淘汰策略:(4)单机版Redis内存优化注意点. 一.内存策略:先来吃份官方文档

Redis 内存淘汰机制

Redis内存淘汰指的是用户存储的一些键被可以被Redis主动地从实例中删除,从而产生读miss的情况,那么Redis为什么要有这种功能?这就是我们需要探究的设计初衷.Redis最常见的两种应用场景为缓存和持久存储,首先要明确的一个问题是内存淘汰策略更适合于那种场景?是持久存储还是缓存? 内存的淘汰机制的初衷是为了更好地使用内存,用一定的缓存miss来换取内存的使用效率. 作为Redis用户,我如何使用Redis提供的这个特性呢?看看下面配置 # maxmemory <bytes> 我们可以通

redis 的过期策略都有哪些?内存淘汰机制都有哪些?

redis 过期策略 redis 过期策略是:定期删除+惰性删除. 所谓定期删除,指的是 redis 默认是每隔 100ms 就随机抽取一些设置了过期时间的 key,检查其是否过期,如果过期就删除. 假设 redis 里放了 10w 个 key,都设置了过期时间,你每隔几百毫秒,就检查 10w 个 key,那 redis 基本上就死了,cpu 负载会很高的,消耗在你的检查过期 key 上了.注意,这里可不是每隔 100ms 就遍历所有的设置过期时间的 key,那样就是一场性能上的灾难.实际上 r

4.redis 的过期策略都有哪些?内存淘汰机制都有哪些?手写一下 LRU 代码实现?

作者:中华石杉 面试题 redis 的过期策略都有哪些?内存淘汰机制都有哪些?手写一下 LRU 代码实现? 面试官心理分析 如果你连这个问题都不知道,上来就懵了,回答不出来,那线上你写代码的时候,想当然的认为写进 redis 的数据就一定会存在,后面导致系统各种 bug,谁来负责? 常见的有两个问题: 往 redis 写入的数据怎么没了? 可能有同学会遇到,在生产环境的 redis 经常会丢掉一些数据,写进去了,过一会儿可能就没了.我的天,同学,你问这个问题就说明 redis 你就没用对啊.re

内存数据持久化的两种常见方法

内存数据持久化的两种常见方法: 1.将内存数据定期dump到磁盘 优点:效率高,操作简便 缺点:会损失部分数据 2.利用类似于mysql的binlog日志的方式,记录更新操作,需要时回放数据 优点:可保证数据完整性 缺点:会损失部分性能,实现稍微复杂点 redis实现了这两种方式

redis过期策略和内存淘汰机制

目录 常见的删除策略 redis使用的过期策略:定期删除+惰性删除 定期删除 惰性删除 为什么要采用定期删除+惰性删除2种策略呢? redis内存淘汰机制 常见的删除策略 1.定时删除:在设置键的过期时间的同时,创建一个timer,让定时器在键的过期时间到达时,立即执行对键的删除操作.(主动删除) 对内存友好,但是对cpu时间不友好,有较多过期键的而情况下,删除过期键会占用相当一部分cpu时间. 2.惰性删除:放任过期键不管,但是每次从键空间中获取键时,都检查取到的键是否过去,如果过期就删除,如