MySQL 8.0新功能监控统计限制连接不再担心被垃圾SQL搞爆内存

作者:GreatSQL社区 时间:2024-01-16 12:51:25 

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)

避免被OOM kill

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

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

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

选项设置值
innodb_buffer_pool_size64G
global_connection_memory_limit12G
connection_memory_chunk_size8192
connection_memory_limit96M
global_connection_memory_trackingON

在上述规划中,设置了每个会话中,普通用户执行的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-variabl...

  • Status Variables: Global_connection_memory, https://dev.mysql.com/doc/refman/8.0/en/server-status-variabl...

  • 【走进RDS】之MySQL内存分配与管理  https://www.jb51.net/article/208197.htm

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

相关链接:

 GreatSQL社区 

 Gitee

 GitHub

来源:https://segmentfault.com/a/1190000043790817

标签:MySQL8.0,监控统计,限制连接
0
投稿

猜你喜欢

  • Python 模拟员工信息数据库操作的实例

    2024-01-20 03:42:04
  • 解决 myJSFrame 框架中 Ajax 方法一处明显的内存泄露

    2008-03-09 19:14:00
  • 你真的了解触发器么 数据实时同步更新问题剖析

    2024-01-24 00:48:40
  • python魔法方法之__setattr__()

    2021-06-06 13:27:47
  • PyInstaller如何打包依赖文件至目标程序目录

    2021-05-31 12:08:12
  • 如何利用Fabric自动化你的任务

    2023-02-25 12:37:04
  • python命令行参数argparse模块基本用法详解

    2023-07-31 03:14:21
  • Windows 7下Python Web环境搭建图文教程

    2023-06-12 07:10:51
  • 如何基于Python制作有道翻译小工具

    2023-10-01 21:00:58
  • 十分钟轻松掌握dataframe数据选择

    2021-03-03 11:11:40
  • Python defaultdict方法使用分析

    2023-01-02 18:05:35
  • 浅谈Python2之汉字编码为unicode的问题(即类似\\xc3\\xa4)

    2021-12-14 07:07:19
  • Python列表如何更新值

    2023-01-28 01:05:22
  • MYSQL初学者使用指南[适用自己安装mysql者]

    2007-08-06 14:53:00
  • Python利用matplotlib生成图片背景及图例透明的效果

    2023-08-22 08:35:18
  • python实现图片,视频人脸识别(opencv版)

    2023-03-14 12:41:07
  • windows安装TensorFlow和Keras遇到的问题及其解决方法

    2022-04-04 02:14:23
  • Python中使用双下划线防止类属性被覆盖问题

    2021-05-04 04:02:44
  • python神经网络Densenet模型复现详解

    2022-02-13 06:43:13
  • python机器学习算法与数据降维分析详解

    2023-09-20 19:40:27
  • asp之家 网络编程 m.aspxhome.com