暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL 8.0不再担心被垃圾SQL搞爆内存的新特性

559

看到叶老师写的这篇文章《MySQL 8.0不再担心被垃圾SQL搞爆内存》,介绍了MySQL 8.0.28引入的新功能,即支持监控统计限制各个连接(会话)的内存消耗,避免大量用户连接因为执行垃圾SQL消耗过多内存,造成可能被OOM kill的风险。一定程度上,避免了开发层面乱用SQL导致数据库问题的场景,很像Oracle的资源管理器。

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

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.

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_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的风险。

但这里可能存在一个前提,就是要充分能预估好SQL可能的正常消耗,避免因为设置了不合理的资源上限导致执行异常,所以很多功能,就像双刃剑,得正确使用,才可以充分发挥积极的作用。

延伸阅读

  • 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


如果您认为这篇文章有些帮助,还请不吝点下文章末尾的"点赞"和"在看",或者直接转发pyq,




近期更新的文章:
最近碰到的一些问题
MySQL多列字段去重实践案例
Oracle Cloud和足球
Oracle 23c值得关注的15项新特性
MySQL日志 - Undo和Redo日志

近期的热文:
推荐一篇Oracle RAC Cache Fusion的经典论文
"红警"游戏开源代码带给我们的震撼

文章分类和索引:
公众号1200篇文章分类和索引

文章转载自bisal的个人杂货铺,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论