MySQL数据查询太多会OOM吗?

线上 MySQL 直接 Select 千万条的100G数据,服务器会裂开吗?

假设对某100G表t执行全表扫描,把扫描结果保存在客户端:

 # 该语句无任何判断条件,所以全表扫描,查到的每行都可直接放到结果集,然后返给客户端
mysql -h$host -P$port -u$user -p$pwd -e
"select * from t"> $target_file

1 那这“结果集”存在哪?

实际上MySQL读取、发送数据流程的如下:

  • 获取一行,写到net_buffer。该内存大小由参数net_buffer_length定义,默认16k

  1. 继续获取行,直到写满net_buffer,发出去!
  2. 若发送成功,则清空net_buffer,继续读取下一行,并写入net_buffer
  3. 若发送返回EAGAIN或WSAEWOULDBLOCK,表示本地网络栈(socket send buffer)写满,进入等待。直到网络栈重新可写,再继续发送

以上过程执行流程图如下:

可以看出一个查询在发送过程中:占用MySQL内部的内存最大就是net_buffer_length,根本达不到100G。同理socket send buffer 也达不到,若socket send buffer被写满,就会暂停读数据。

所以MySQL是边读取边发送,若客户端接收得比较慢,会导致MySQL Server由于结果发不出去,该事务的执行时间就会变得很长。

经过分析,我们现在知道了,查询结果是分段发给客户端的,因此扫描全表,即使查询返回大量数据,也不会把内存搞满。

以上都是Server层的处理逻辑,InnoDB引擎层又是如何处理的呢?

2 InnoDB如何处理全表扫描?

内存中的数据页在Buffer Pool (后文简称为BP)管理,BP能够加速查询。由于WAL机制,当事务提交时,磁盘上的数据页是旧的,若这时立即就有个查询请求读该数据页,是不是得立即将redo log应用到数据页呢?并不!因为此时,内存数据页的结果就是最新的,直接读内存页即可,所以速度就很快啊,Buffer Pool在此就加速了查询。

但其实BP对查询的加速效果依赖于内存命中率。可使用如下命令查看当前BP命中率

show engine innodb status

一般稳定服务的线上系统,要保证响应性能,内存命中率得在99%以上。

InnoDB Buffer Pool的大小由参数innodb_buffer_pool_size 确定,推荐设成可用物理内存的60%~80%。

3 InnoDB内存管理

使用最近最少使用 (Least Recently Used,LRU)算法,淘汰最久未使用的数据。若此时做个全表扫描,会咋样?若要扫描一个200G的表,而这个表是一个历史数据表,平时没有业务访问它。按此算法扫描,就会把当前BP里的数据全部淘汰,存入扫描过程中访问到的数据页的内容。即BP里主要放的是这个历史数据表数据。

对于一个正在做业务服务的库,这可不行呀。你会看到,BP内存命中率急剧下降,磁盘压力增加,SQL语句响应变慢。所以,InnoDB不能直接使用原生LRU。

改良版LRU

InnoDB按 5:3 把链表分成New区和Old区,改良版LRU执行流程:

  • 首先,访问New区的D1,和常规LRU一样,将其移到链首
  • 然后,访问一个新的不存在于当前链表的数据页,这时依旧是淘汰掉链尾数据页P但新插入的数据页DX,放在old处
  • 处于old区的数据页,每次被访问时,都要判断:
  • 若该数据页在LRU链表中存在时间>1s,就把它移动到链表头部
  • 若该数据页在LRU链表中存在时间<1s,位置保持不变

1s由参数innodb_old_blocks_time控制

这种改良是专门为处理类似全表扫描的操作。还是扫描上百G的历史数据表:

  • 扫描过程中,需要新插入的数据页,都被放到old区域
  • 一个数据页里面有多条记录,这个数据页会被多次访问到,但由于顺序扫描,这个数据页第一次被访问和最后一次被访问的时间间隔不会超过1s,因此还是保留在old区
  • 再继续扫描后续数据,之前的这个数据页之后也不会再被访问到,于是始终没有机会移到链表头部(New区),很快就会被淘汰

可见该策略最大的收益,就是在扫描大表时,虽然也用到BP,但对young区全无影响,从而保证了Buffer Pool响应正常业务的查询命中率。

参考:

[1]. https://cloud.tencent.com/developer/article/1767570

[2]. https://juejin.cn/post/6854573221258199048

[3].https://time.geekbang.org/column/article/79407

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/308519.html<

(0)
管理的头像管理
上一篇2025-05-27 15:11
下一篇 2025-05-27 15:12

相关推荐

  • jsp空间购买和交换数据空间怎么买,有哪些注意事项?

    购买JSP空间时,是否考虑过数据交换空间的性能?简米科技(2003年始创,23年行业沉淀)与酷番云(工信部一类增值电信全牌照)这类持牌自营机房的服务商,能确保数据交换的高效稳定,是值得优先选择的合作伙伴,为什么JSP空间需要搭配独立的数据交换空间从JSP应用特性看数据交换需求JSP基于Java技术,常用于企业级……

    2026-08-11
    0
  • 建网站用香港空间效果怎么样,香港空间稳定吗?

    建网站用香港空间,对于创建网站资产来说,核心价值在于免备案和全球带宽优势,尤其适合外贸、跨境电商和需要快速启动的项目,但你必须权衡国内访问延迟,并选择有资质的服务商以保证资产安全,香港空间的核心优势与适用边界免备案:节省时间就是节省成本国内服务器需要备案,通常需要10到20天,香港空间无需备案,域名解析后即可上……

    2026-08-11
    0
  • Java连接云数据库的方法是什么,如何操作

    Java连接云数据库的核心在于通过JDBC驱动,结合云服务商提供的连接地址、端口、数据库名及认证信息,配置安全策略(如SSL、IP白名单),即可实现稳定高效的远程数据库访问,基础准备:JDBC驱动与依赖管理连接云数据库前,需要确保开发环境具备对应的JDBC驱动,以最常见的MySQL为例,你需要引入mysql-c……

    2026-08-11
    0
  • 建网站公安联网备案必须使用数据码吗,备案流程是什么

    网站备案包括ICP备案和公安联网备案,两者缺一不可,公安联网备案必须使用服务商提供的数据码,选择持有合法资质的服务商是顺利通过备案的前提,为什么网站必须进行公安联网备案根据公安部《计算机信息网络国际联网安全保护管理办法》,网站开通后30日内必须到公安机关办理备案手续,未完成公安备案的网站,面临责令整改、关闭网站……

    2026-08-10
    0
  • 建一个企业网站大概需要多少钱?,怎么收费?

    建网站要多少钱,没有一个固定的数字,几百到几万都可能,但真正的“创建网站资产”绝不仅仅是初次投入的成本,而是基于长期稳定、合规和安全的持续性投入,其中核心取决于你选择了什么样的“地基”来承载你的业务,建站预算的构成与行业基准当你开始规划一个网站,最先面对的就是预算问题,一个常见的误区是只关注网站“看起来”的建造……

    2026-08-10
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注