登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
签到
每天签到奖励2-10圆
导读
排行榜
TG频道
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
VIP申请
VIP网盘
网盘
联系我们
发帖说明
每日签到
道具
勋章
任务
淘帖
动态
分享
留言板
导读
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
MySQL 33 我查这么多数据,会不会把数据库内存打爆? ...
MySQL 33 我查这么多数据,会不会把数据库内存打爆?
[ 复制链接 ]
辗振
6 天前
有这样一个问题:主机内存只有100G,现在要对一个200G的大表做全表扫描,会不会把数据库主机的内存用完?想想逻辑备份,也是整库扫描,因此对大表做全表扫描看起来是没有问题的,那么这个流程到底是怎样呢?
全表扫描对server层的影响
假设现在要对一个200G的InnoDB表db1.t执行全表扫描,若要把扫描结果保存在客户端,会使用命令:
mysql -h$host -P$port -u$user -p$pwd -e "select * from db1.t" > $target_file
复制代码
由于数据保存在主键索引上,所以全表扫描实际是直接扫描主键索引。该语句没有其他判断条件,所以查到的每一行都可以直接放到结果集,然后返回给客户端。
那么结果集是存在哪里呢?
实际上服务端并不需要保存一个完整的结果集,取数据和发数据的流程为:
获取一行,写到net_buffer中,这块内存的大小由参数net_buffer_length定义,默认16k;
重复获取行,直到net_buffer写满,调用网络接口发出去;
如果发送成功,清空net_buffer,然后继续取下一行并写入net_buffer;
若发送函数返回EAGAIN或WSAEWOULDBLOCK,表示本地网络栈写满,进入等待。直到网络栈重新可写,再继续发送。
流程图:
从中可以看到:
一个查询在发送过程中,占用的MySQL内部的内存最大就是net_buffer_length这么大;
socket send buffer(大小定义/proc/sys/net/core/wmem_default)如果被写满,会暂停读数据的流程。
即MySQL是边读边发的,如果客户端接收慢,会导致MySQL发不出去,事务的执行时间变长。此时如果使用show processlist命令:
state若一直处于sending to client,就表示服务器端的网络栈写满了。
上一篇文章曾说到,若客户端使用-quick参数,会使用mysql_use_result方法,该方法是读一行处理一行。假设有一个业务的逻辑比较复杂,每读一行要处理很久,就会导致客户端过很久才会取下一行数据,就可能出现上图的情况。
因此,对于正常的线上业务来说,如果一个查询的返回结果不会很多,建议使用mysql_store_result,直接把查询结果保存到本地内存。
如果要快速减少处于sending to client状态的线程数量,将net_buffer_length参数设置为一个更大的值是一个可选方案。
另外有一个看起来像的状态是sending data,有时候能看到很多查询语句的状态是sending data,但查看网络没什么问题,这是为什么?
实际上,一个查询语句的状态变化为:
MySQL查询语句进入执行阶段后,首先把状态设置为sending data;
发送执行结果的列相关的信息给客户端;
继续执行语句流程;
执行完成,把状态设置成空字符串。
也就是说sending data并不一定指正在发送数据,而可能是处于执行器过程中的任意阶段。
那么知道了server层的处理逻辑,在InnoDB引擎里又是怎么处理的呢?
全表扫描对InnoDB的影响
之前介绍WAL机制时,分析了InnoDB内存的一个作用是保存更新结果,再配合redo log避免随机写盘。内存数据页是在Buffer Pool中管理,因此在WAL里Buffer Pool起到了加速更新的作用。
实际上,Buffer Pool还有加速查询的作用。由于有WAL机制,当事务提交时,磁盘上的数据页是旧的,此时如果马上有一个查询要来读这个数据页,其并不需要读磁盘,而是直接读内存页。而Buffer Pool对查询的加速效果,依赖于一个重要的指标:内存命中率。
可以执行show engine innodb status命令,结果中的Buffer Pool hit rate,就表示当前的命中率。一般情况下,一个稳定的线上系统,要保证响应时间符合要求的话,内存命中率要在99%以上。若所有查询需要的数据页都能直接从内存得到,那命中率就是100%,但这在实际生产中很难做到。
Buffer Pool的大小由参数innodb_buffer_pool_size确定,一般建议设置成可用物理内存的60%-80%。如果一个Buffer Pool满,而又要从磁盘读入一个数据页,就肯定要淘汰一个旧数据页,InnoDB使用的是LRU算法,淘汰最久未使用的数据。
如果是平时我们理解的LRU,要全表扫描的话,会有些问题。比如要扫描一个200G大小,平时没有业务访问的历史数据表。若按基础的LRU,会把当前的Buffer Pool里的数据全部淘汰,存入扫描过程中访问到的数据页内容,即Buffer Pool里主要存放历史数据表数据,那么此时会对其他业务造成很大影响,Buffer Pool的内存命中率将会急剧下降,磁盘压力增加,SQL语句响应变慢。
因此,InnoDB对LRU算法做了改进。
在InnoDB实现上,按照5:3比例将整个LRU链表分为young区域和old区域,上图中LRU_old指向old区域的第一个位置,是整个链表的5/8处,即靠近链表head的5/8区域为yong区域,靠近链表tail的3/8区域是old区域。改进后的LRU算法执行流程为:
state 1,要访问数据页P3,由于P3在young区域,因此和优化前的LRU算法一样,将其移到链表头,即state 2;
state 3,想要访问一个新的、不存在于当前链表的数据页,此时会淘汰尾部的数据页Pm,将新插入的数据页Px放在LRU_old处。
处于old区域的数据页,每次访问时需要做如下判断:
若该数据页在LRU链表存在时间超过了1秒,就把它移到链表头;
否则该数据页位置保持不变。“1秒”这个时间由参数innodb_old_blocks_time控制。
以上策略就是为了处理类似全表扫描的操作量身定制的。以扫描200G的历史数据表为例:
扫描过程中,需要新插入的数据页都会放到old区域;
一个数据页有多条记录,由于顺序扫描,这个数据页第一次被访问和最后一次被访问的时间间隔不会超过1秒,因此还是会留在old区域;
再继续扫描后续的数据页,之前的数据页由于不会再被访问到,始终没有机会移到head,之后很快会从old区域淘汰出去。
可以看到,该策略最大的收益是在扫描大表的过程中,虽然也用到Buffer Pool,但是对young区域完全没有影响,从而保证Buffer Pool响应正常业务的查询命中率。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
MySQL
我查
这么
数据
会不
相关帖子
MySQL binlog筛选参数和复制筛选参数
MySQL之B+树分析
MySQL的基本语法(增,删,改,查)
技术解读GaussDB (for MySQL)流控机制
MySQL面试题汇总
.NET驾驭Word之力:数据驱动文档 - 邮件合并与自定义数据填充完全指南
百度商户采集用户数据程序
从零开始学Flink:数据输出的终极指南
SpringBoot进阶教程(八十七)数据压缩
MYSQL主从配置
vip免费申请,1年只需15美金$
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
安全
MySQL binlog筛选参数和复制筛选参数
0
800
肿圬后
2025-10-07
安全
MySQL之B+树分析
0
765
黎瑞芝
2025-10-07
安全
MySQL的基本语法(增,删,改,查)
0
974
毡轩
2025-10-07
安全
技术解读GaussDB (for MySQL)流控机制
0
930
亢安芙
2025-10-07
安全
MySQL面试题汇总
0
896
崔瑜然
2025-10-07
安全
.NET驾驭Word之力:数据驱动文档 - 邮件合并与自定义数据填充完全指南
0
721
撇瞥
2025-10-08
程序
百度商户采集用户数据程序
0
13
新程序
2025-10-08
业界
从零开始学Flink:数据输出的终极指南
0
194
锷稠
2025-10-08
业界
SpringBoot进阶教程(八十七)数据压缩
0
397
坏级尹
2025-10-08
安全
MYSQL主从配置
0
546
时思美
2025-10-09
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
浏览过的版块
程序
安全
代码
签约作者
程序园优秀签约作者
发帖
辗振
6 天前
关注
0
粉丝关注
17
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
anyue1937
9999501
dage888
999994
富账慕
10013
4
匝抽
9986
5
孙淼淼
9992
6
筒濂
9985
7
柴古香
9993
8
凌彦慧
9991
9
崔瑜然
9984
10
慢秤
9979
查看更多