当前位置: 首页 > news >正文

数据库占用内存过高?

前言

大家好!我是【提前退休的java猿】(抖音同号)👏

昨天有位粉丝私信我“数据库占用内存过高,如何优化?”,今天就和大家分享一下如何解决数据库占用内存过高的问题

在这里插入图片描述

数据库内存占用过高

要解决问题肯定就得找到问题的原因?

使用内存监控工具:通过top、htop(Linux)监控数据库进程(如mysqld、postgres)的内存占用,结合数据库自带工具(如 MySQL 的SHOW ENGINE INNODB STATUS)分析内存使用细节

一、排查内存过高的原因

首先然后想到的当然就是SQL写法上的优化,其次就是数据库配置,或者系统架构的问题了,比如并发太高数据库的活跃线程比较高等问题

哪些SQL会占用很高的内存呢?

  • 大结果集查询,查询大量的字段(select *)且没有分页
  • join查询使用不当。join连查询如果表数据量大也是非常占用内存的。join的底层实现有好几种算法,想了解的可以参考: sql 中谨慎使用多表join;
  • 是否有很多长事务,导致内存始终得不到释放(比如索引失效等问题)

排查方法我们可以通过SQL命令查看此时活跃得线程的查询信息(PGSQl为例):

SELECT pid,                -- 进程IDusename AS user,    -- 执行查询的用户datname AS db,      -- 连接的数据库client_addr,        -- 客户端IP地址application_name,   -- 应用程序名称backend_start,      -- 后端进程启动时间query_start,        -- 查询开始时间state_change,       -- 状态变更时间state,              -- 会话状态(active/running/idle等)wait_event_type,    -- 等待事件类型wait_event,         -- 具体等待事件query               -- 当前执行的SQL语句(可能被截断)
FROM pg_stat_activity
WHERE state = 'active'    -- 只显示活跃状态的查询
ORDER BY query_start DESC;   -- 按查询开始时间倒序排列

通过查看目前执行的SQL情况,来排查是SQL不规范或者是SQL需要优化。如果定位到SQL符合上面的情况,要优化就自然而然的就很简单了。

查看需要的字段,分页处理;多次查询,内存组装,减少数据库压力和内存;优化代码逻辑减少事务执行时间。

数据库配置

只能说数据库配置,能优化数据库对占用问题,并且不是解决根本问题方式吧。还是带大家看一下,配置层面对内存有什么影响以及怎么去解决这个。

  • MySQL/InnoDB 示例

    • 链表查询缓存join_buffer_size :没有索引的join查询时候,会把数据查询到内存中匹配。这个就是控制内存的缓存大小的。可以排查是否是设置得太大,可以降低这个缓存配置

    • 缓冲池(innodb_buffer_pool_size) :这是 InnoDB 最核心的内存消耗项,建议设置为系统可用内存的 50%-70%(避免占用过高导致系统 OOM)。
      例如:innodb_buffer_pool_size = 8G(若系统内存为 16G)。

    • 连接数(max_connections) :过多连接会占用大量内存,需根据实际并发量调整,避免设置过大(根据业务调整测试吧)。(设置得太大,并发高的时候全都压到数据库了)

    • 临时表内存(tmp_table_size、max_heap_table_size) :限制内存临时表大小,超过则自动转为磁盘表,避免内存溢出。
      例如:tmp_table_size = 64Mmax_heap_table_size = 64M

    • 查询缓存(query_cache_size) :MySQL 8.0 已移除该功能,低版本若开启,建议关闭(query_cache_type = 0),避免缓存失效时的内存消耗。

  • PostgreSQL 示例

    • 共享缓冲区(shared_buffers) :建议设置为系统内存的 25%(默认较小,需手动调大)。
    • 工作内存(work_mem) :每个查询的排序、哈希操作使用的内存,根据并发查询数调整(如work_mem = 16M,避免单个查询占用过多)。
    • 最大连接数(max_connections) :默认 100,过高会导致内存激增,建议结合连接池(如 PgBouncer)控制。

架构上做调整

如果SQL和配置都排查了或者优化了,还是出现占用内存过高。估计就是并发太高了。这个时候就需要在架构上做相应的调整了!

  • 做限流处理,或者使用消息队列流量削峰,减少数据库压力,从而减少内存

  • 使用缓存如redis,缓存热点数据。从而减少数据库内存占用问题

  • 对于超大表,可通过分区表(按时间、地域拆分)或分库分表(如 ShardingSphere)分散数据量,降低单库内存压力。

总结

解决数据库内存过高的核心思路是:先定位原因(查询、配置、连接等),再针对性优化(调参数、改查询、控连接) ,同时结合监控工具长期跟踪内存变化,避免问题复发。

如果是高并发场景,那就需要调整 系统架构,包括引入中间件、限流、缓存等等措施,同时数据库架构也需要做相应的调整(如读写分离、分库分表),从根本上降低单节点内存压力。

http://www.lryc.cn/news/595281.html

相关文章:

  • Windows防火墙配置详解
  • 设备虚拟化与动态路由核心技术
  • AJAX 概念与 axios 使用
  • visual studio安装错误
  • Grok网站的后端语言是php和Python2.7
  • Linux——自制shell命令行解释器
  • Linux的系统调用机制总结
  • linux定时器使用
  • 如何优化Java的原生反射Method.invoke()
  • Linux--初识linux
  • c++找工作(qt)
  • (二)Unity3d-ROS联合仿真:运行Unity-Robotics-Hub
  • 【Linux庖丁解牛】— 线程控制!
  • 教育数字化革命:低代码破局与未来展望
  • 今日行情明日机会——20250721
  • (一)ZooKeeper 发展历史
  • 计算机发展史:人工智能时代的智能变革与无限可能
  • CLIP与SIGLIP对比浅析
  • oracle 数据库中,将几张表的数据按指定日期范围实时同步至同一个数据库的备份表中。
  • 详解 F.cross_entropy 与标签平滑的工作原理
  • Day07_网络编程20250721(网络编程考试试卷)
  • 比特币技术简史 第五章:交易机制 - UTXO模型、脚本系统与多重签名
  • PyCharm 未正确关联 .jpg 为图片格式
  • 玩转Rocky Linux 9 部署Redis指南
  • Jmeter如何做接口测试?
  • 前端之学习后端java小白(一)之SDKMAN
  • JavaScript的引入方式和基础语法的快速入门与学习
  • DigitalOcean 云平台上线 AMD MI325X GPU Droplet 服务器
  • 网站域名备案和服务器有关系吗
  • 解决OpenHarmony中找不到pthread_cancel和pthread_setcanceltype等libc符号的问题