MySQL 8.0不再担心被垃圾SQL搞爆内存

这篇具有很好参考价值的文章主要介绍了MySQL 8.0不再担心被垃圾SQL搞爆内存。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

MySQL 8.0.28引入的新功能

MySQL 8.0.28开始,新增一个特性,支持监控统计限制各个连接(会话)的内存消耗,避免大量用户连接因为执行垃圾SQL消耗过多内存,造成可能被OOM kill的风险。

首先,需要先设置系统选项 global_connection_memory_tracking = 1,之后可以通过系统状态变量 Global_connection_memory 查看当前所有连接消耗的内存总量:

mysql> show global status like 'Global_connection_memory';
+--------------------------+---------+
| Variable_name            | Value   |
+--------------------------+---------+
| Global_connection_memory | 1122912 |
+--------------------------+---------+

系统选项 global_connection_memory_tracking 可以全局开启,也可以在单个会话中独立开启。如果是全局开启,则会针对所有连接统计内存消耗情况,包括系统内部线程,以及root用户创建的连接;如果是单个会话中独立开启,则只会统计当前会话连接的内存消耗。此外,InnoDB buffer pool不在统计范围内。

可以通过设置选项 connection_memory_chunk_size 来控制内存统计更新频率,该选项默认值为8KB,也就是当内存使用变化超过8KB时,才会更新统计结果。

可以调整每个会话连接可使用内存上限,由选项 connection_memory_limit 定义其限制,默认值及最大值都是 18446744073709551615,这个默认值太大了,等同于没有限制。如果线上经常运行垃圾SQL导致MySQL内存消耗过大的话,可以适当调低这个选项。

如何在评估一条SQL可能要消耗多少内存呢?可以先调整选项值 connection_memory_limit = 2097152,即调低到2MB。然后以普通用户身份(没有SUPER、SYSTEM_VARIABLES_ADMIN、SESSION_VARIABLES_ADMIN等权限)执行相应的SQL,如果预估需要消耗的内存超过2MB,则会发出类似下面的报错,并且这个连接会被杀掉断开:

mysql> select @@global.connection_memory_limit;
+----------------------------------+
| @@global.connection_memory_limit |
+----------------------------------+
|                          2097152 |
+----------------------------------+

mysql> select count(c) from t group by c;
ERROR 4082 (HY000): Connection closed. Connection memory limit 2097152 bytes exceeded. Consumed 7079568 bytes.

可以看到上述报错信息中提示这条SQL需要消耗约 7079568字节 的内存。当然了,实际上这条SQL需要消耗的内存不止 7079568字节,随着我们细粒度逐步上调 connection_memory_limit 选项值,最后会发现这条SQL需要消耗的内存约为 13087952字节。

当执行完这条SQL后,我们再次查询状态变量 Global_connection_memory,会发现它的值并没这么大,说明这条SQL执行完毕后,相应的内存也立即释放,只保留维持会话连接所需的基本内存:

mysql> select count(c) from t group by c; show global status like 'Global_connection_memory'; show session status like 'Global_connection_memory';
+----------+
| count(c) |
+----------+
|        2 |
+----------+
1 row in set (0.04 sec)

+--------------------------+---------+
| Variable_name            | Value   |
+--------------------------+---------+
| Global_connection_memory | 2193153 |
+--------------------------+---------+
1 row in set (0.00 sec)

前面提到一点,只有普通用户执行SQL才会受到内存使用上限约束,如果是用root用户执行同一条SQL,则不受限制:

mysql> select user();
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

mysql> select @@global.connection_memory_limit;
+----------------------------------+
| @@global.connection_memory_limit |
+----------------------------------+
|                          2097152 |
+----------------------------------+
1 row in set (0.00 sec)

mysql> select count(c) from t group by c;
+----------+
| count(c) |
+----------+
|        2 |
+----------+
1 row in set (0.05 sec)

所以不能频繁用root等具备SUPER权限的用户执行需要大内存的SQL,避免被OOM kill。

另外,选项 connection_memory_chunk_size 如果设置太小,则会频繁更新内存统计,对系统性能也会有影响;但也不建议设置太大,否则可能因为更新不及时而引发OOM问题,大部分情况下采用默认值即可。

综上,假设有个服务器物理内存是96GB,建议考虑做如下分配:

选项 设置值
innodb_buffer_pool_size 64G
global_connection_memory_limit 12G
connection_memory_chunk_size 8192
connection_memory_limit 96M
global_connection_memory_tracking ON

在上述规划中,设置了每个会话中,普通用户执行的SQL消耗内存不能超过96MB,所有会话消耗的内存总量不超过12GB,约可最高支撑128个并发连接;此外,innodb buffer pool + 各会话内存的和是 76G,约为物理内存的80%,已给系统预留出基本充足的剩余内存,降低发生SWAP的风险。

延伸阅读

  • Changes in MySQL 8.0.28, https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-28.html
  • sys var: global_connection_memory_limit, https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html
  • Status Variables: Global_connection_memory, https://dev.mysql.com/doc/refman/8.0/en/server-status-variables.html
  • 【走进RDS】之MySQL内存分配与管理(下篇), https://mp.weixin.qq.com/s/CCbbmdV-stMogtby6M4DqA

Enjoy GreatSQL 😃

关于 GreatSQL

GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。

相关链接: GreatSQL社区 Gitee GitHub Bilibili

GreatSQL社区:

社区博客有奖征稿详情:https://greatsql.cn/thread-100-1-1.html

MySQL 8.0不再担心被垃圾SQL搞爆内存

技术交流群:

微信:扫码添加GreatSQL社区助手微信好友,发送验证信息加群

MySQL 8.0不再担心被垃圾SQL搞爆内存文章来源地址https://www.toymoban.com/news/detail-446029.html

到了这里,关于MySQL 8.0不再担心被垃圾SQL搞爆内存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据库操作不再困难,MyBatis动态Sql标签解析

    MyBatis缓存原理 Mybatis的CachingExecutor与二级缓存 Mybatis plugin 的使用及原理 MyBatis四大组件Executor、StatementHandler、ParameterHandler、ResultSetHandler 详解 MyBatis+Springboot 启动到SQL执行全流程 使用MyBatis,或者MyBatis-plus,有一项重要的开发技能就是写动态sql,动态sql能帮我们省略很多复杂逻

    2024年02月12日
    浏览(62)
  • jvm垃圾回收及内存模型

    1、了解垃圾回收之前,必须先了解内存模型 jdk1.8后,元空间是 方法区的具体实现 (方法区是规范,之前叫永久代)   1)运行时常量池  就是字节码生成的Class对象包含上述的常量池       2、垃圾回收区域    a、 首先要标记垃圾,找出垃圾      b、Java垃圾回收(一)_java 垃

    2024年02月08日
    浏览(48)
  • Golang内存分配及垃圾回收

      为什么需要垃圾回收? 自动释放不需要的对象,让出存储器资源,无需程序员手动执行 Go V1.3之前是标记-清除算法 具体步骤 缺点:程序卡顿、扫描整个heap、数据清除会产生heap碎片 V1.3之后,做了简单的优化 V1.5之后,使用三色并发标记法 只要是新创建的对象,默认颜色都

    2024年02月13日
    浏览(38)
  • JVM学习 GC垃圾回收机制 (堆内存结构、GC分类、四大垃圾回收算法)

    🤖 作者简介: 努力的clz ,一个努力编程的菜鸟 🐣🐤🐥   👀 文章专栏: 《JVM 学习笔记》 ,本专栏会专门记录博主在学习 JVM 中学习的知识点,以及遇到的问题。   🙉 文章详情: 本篇博客是学习 【狂神说Java】JVM快速入门篇 的学习笔记,关于 GC垃圾回收机制 (堆内存结

    2023年04月19日
    浏览(35)
  • 2.6. Java内存管理与垃圾回收

    2.6.1. Java内存模型 在Java中,内存被划分为以下几个区域: 堆(Heap):存储对象实例和数组,是垃圾回收的主要区域。 栈(Stack):存储局部变量和方法调用。每个线程有自己的栈。 方法区(Method Area):存储类信息,如类的结构、方法、字段等。 本地方法栈(Native Method

    2024年02月07日
    浏览(34)
  • JVM之内存与垃圾回收篇2

    PC Register是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError的区域。 为什么要有PC寄存器? 因为CPU会在不同的线程之间来回切换,切换回来之后,需要知道接着从哪里开始执行。 JVM字节码解释器需要通过改变PC寄存器中的值来明确下一条应该执行什么样的字节码指令。

    2024年02月17日
    浏览(42)
  • [Unity]⭐浅谈Unity内存优化,内存碎片?僵尸内存?以及什么是GC垃圾回收机制。

    目录 🟥 一、什么是内存? 1.物理内存   2.虚拟内存 🟧 二、Unity的内存 1.Unity的内存分类 2.游戏运行时内存占用情况 3.什么是MONO内存? 4.内存碎片、僵尸内存 🟨三、GC 垃圾回收 1.定义 2.一张图清晰得看一下流程~ 3.GC的作用及步骤 4.GC存在的问题及优化策略 🟩 四、内存优

    2024年02月03日
    浏览(41)
  • JVM学习之内存与垃圾回收篇1

    2000年,JDK 1.3发布,Java Hot Spot Virtual Machine正式发布,成为Java的默认虚拟机。 2006年,JDK 6发布。同年,Java开源并建立了OpenJDK。顺理成章,Hotspot虚拟机也成为了OpenJDK中的默认虚拟机。 2008年,Oracle收购了BEA,得到了JRockit虚拟机。 2010年,Oracle收购了Sun,获得了Java的商标和Ho

    2024年02月16日
    浏览(50)
  • JVM—内存管理(运行时数据区)、垃圾回收

    当JVM类加载器加载完字节码文件之后,会交给执行引擎执行,在执行的过程中会有一块JVM内存区域来存放程序运行过程中的数据,也就是我们图中放的运行时数据区,那这一块运行时数据区究竟帮我们做了哪些工作?我们常说的线上内存泄漏和内存溢出是因为什么?我们今儿

    2024年02月13日
    浏览(34)
  • 苹果手机怎么清理内存垃圾?2个方法,快速解决

    很多小伙伴在生活中会使用手机来看视频、聊天、学习等等。不管是苹果手机还是安卓手机,使用手机的时间长了,里面就会产生很多垃圾占据手机空间。苹果手机怎么清理内存垃圾?今天小编就来分享2个方法,教你快速解决。   很多小伙伴不知道苹果手机怎么清理内存垃

    2024年02月16日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包