恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
SUSE系统SAP HANA内存不足故障排查与调优实战指南
首页
资讯中心
/
SUSE系统SAP HANA内存不足故障排查与调优实战指南
SUSE系统SAP HANA内存不足故障排查与调优实战指南
发布时间:2026/9/16 4:57:11
开门见山说一句SUSE Linux SAP HANA 这套组合在企业级 ERP 场景里太常见了但“内存不足”这个老毛病也是我处理了不知道多少次的头号故障。最典型的一幕就是HANA 把系统内存吃满SAP 客户端登不进去集成平台全线报错业务部门电话直接打爆运维群。更头疼的是这个问题不像磁盘满那么直观有时候 free 一看内存好像还有但 SAP 就是连不上有时候明明刚重启过过两天又告警了。这篇文章我把这些年处理 SUSE 系统上 SAP HANA 内存不足问题的完整思路摊开讲。从最基础的现象判断、根因分析到系统层和 HANA 层的监控诊断再到应急恢复、参数调优、内核加固最后是我实际踩过的坑和排查经验。不管你是刚接手 SAP 运维的新人还是被这个问题折磨过很多次的老人照着这条线走一遍基本能把“内存不足导致 SAP 应用不可用”的问题理顺。1. 问题现象与根因分析先弄懂 SAP HANA 为何总“吃”内存1.1 故障现象一套 SAP 系统从卡顿到瘫痪的全过程这类故障不是突然一下就爆掉的。我遇到过的生产事故几乎都有一个从量变到质变的过程。初期阶段用户反馈业务系统变慢。SAP GUI 登录的时候明显卡顿双击事务代码要等好几秒才出界面运行报表偶尔超时。这个阶段去 HANA Studio 里看内存使用率大概在 80% 到 90% 左右系统整体的 load average 也开始往上走但核心业务还能勉强撑住。中期阶段问题开始恶化。操作系统为了满足内存需求开始疯狂回收 page cache导致磁盘 IO 大幅上升。因为 cache 被回收之后文件系统读写都要重新走磁盘整个系统的响应速度进一步下降。此时 ssh 上服务器执行命令都能感觉到明显延迟free 输出里 available 已经非常低。到了爆发阶段HANA 数据库直接无法响应连接。SAP 应用服务器ABAP/Java 实例报出类似于“数据库连接不存在”“会话已中断”的错误SAP GUI 直接弹窗提示无法登录。登录到 SUSE 系统上看内存几乎被耗尽甚至可能已经在/var/log/messages里看到 Out of Memory 相关日志说明 OOM Killer 已经介入了。这个阶段不管怎么重启 SAP 应用服务都没用因为根子在数据库这一层。1.2 根因拆解HANA 内存池和系统内存的博弈要搞清楚为什么 HANA 会导致系统内存不足先要理解 HANA 的特殊性。SAP HANA 是一个内存数据库它的核心设计理念就是“数据的主副本常驻内存”。传统数据库先把数据放在磁盘内存只是缓存层HANA 反过来了数据加载进内存后所有查询分析都在内存里直接跑磁盘只负责持久化和日志。所以 HANA 进程一启动就会向操作系统申请一大块内存作为自己的内存池这个池子内部再按用途细分比如列存储表数据、行存储表数据、增量存储delta store、日志缓冲区、排序栈空间、会话上下文等等。你从操作系统层面看HANA 就是那个占内存最多的进程动辄几百 GB完全是正常现象。问题在于 HANA 的内存池是有“惰性”的。它分配出去的内存不会轻易还给操作系统因为频繁的 malloc 和 free 会产生内存碎片影响稳定性。哪怕你删掉了一些大表、跑完了一个大查询HANA 内部可能把这块内存标记为“可用”但不会马上归还给 OS。这就造成一个诡异的现象系统层面看 used 内存居高不下但 HANA 内部实际可能还有不少空闲内存池可供复用。当 SUSE 系统物理内存真的不够用时内核会启动各种机制来“挤内存”回收页缓存、压缩内存页、把匿名页换到 swap最后实在不行就启动 OOM Killer 杀进程。问题就出在这——OOM Killer 的评分机制通常是按进程占用内存大小来排的HANA 这种巨型进程几乎每次都会成为首选目标。一旦 HANA 进程被杀整个 SAP 系统直接瘫痪。1.3 常见误区为什么 free 命令显示的内存“不够用”是假象很多新手看 SUSE 系统的内存习惯用free -g然后盯着 used 那一列看。一看 used 接近 100%就慌得不行立刻判断“内存不足”。这里有一个长期存在的认知误区。Linux 的内存管理哲学是“内存闲着也是闲着不如拿来缓存”。它会尽量把空闲内存用作 page cache用来加速文件读写。所以在free的输出里used 很高不代表真的不够用关键要看 available 这一列。available 才是“在不触发大量 swap 的情况下还能分配给新进程的内存估算值”。有时候 used 显示 98%available 还有 20%系统完全健康有时候 used 只有 80%但 available 已经趋近于 0那才是真的要出事。SAP HANA 环境下更容易踩这个坑因为 HANA 的内存池占用量太高把 page cache 挤得没地方待。系统必然频繁回收 cache然后新的内存请求再挤压 cache最终进入“内存不足”的恶性循环。所以处理此类问题时第一步不是急着重启也不是立刻扩容而是先用正确的指标判断现状。2. 内存监控与诊断动手抢救前先看清内存去哪了2.1 系统级命令free、top、vmstat、pidstat 的正确打开方式先说最基础的系统层排查。我一般按以下顺序来第一个命令永远是free -g。注意看 total、used、available 三列顺带看 swap 的 used 和 available。重点判断两点available 是否已经低到危险值低于总内存的 5% 就算很危险swap 是否有大量使用。如果 si/so 一直在跳说明系统已经靠换页在续命必须尽快介入。然后是top。进去之后按大写 M 按内存排序一眼就能看到到底是谁在吃内存。正常情况肯定是 HANA 的进程排最前面比如/usr/sap/SID/HDBinstance/hostname。如果看到其他非业务进程也占用了大量内存比如 Java 应用服务器、Web 服务、监控 agent就要考虑是不是这些进程的配置有问题抢了 HANA 的资源。再细一点用pidstat -r -p PID 1可以持续观察某个进程的 RSS、%MEM 变化。特别是 HANA 进程如果 RSS 持续上涨且不回落说明 HANA 内部某个东西在泄漏或数据量在增长。vmstat 1也是必看。重点看 si、so、free、cache、us、wa 这几列。如果 si/so 频繁非零说明内存已经严重不足系统在 swap 进 swap 出。此时哪怕业务看起来还能用性能也已经大打折扣了。2.2 HANA 内部诊断HANA Studio 与 SQL 视图定位内存大户系统层看清了之后下一步要进 HANA 内部看。因为 HANA 是一个整体占用很大的进程但你要搞清楚它到底是哪部分吃掉了内存才能对症下药。最简单的入口是 HANA Studio 的 Administration 视图里面有 Memory 相关的标签页可以直观看到整个 HANA 实例的内存使用情况Total allocated memory、Peak allocated memory、Effective limit 等。Effective limit 这个字段特别关键它就是当前 HANA 实例允许分配的内存上限。在命令行或者 DBA Cockpit 里我更推荐直接跑 SQL 来查信息更细、更快。常用的几个视图和查询如下-- 全局内存概览重点看 memory_limit / total_memory / allocated_memory SELECT * FROM M_MEMORY; -- 主机级内存统计看物理内存与 HANA 进程占用的关系 SELECT * FROM M_HOST_MEMORY_STATISTICS; -- 各服务组件的堆内存分配情况 SELECT * FROM M_HEAP_MEMORY_ALLOCATION; -- 各列存储表的实际内存占用找大表 SELECT SCHEMA_NAME, TABLE_NAME, PART_ID, SUM(MEMORY_SIZE_IN_TOTAL) FROM M_CS_TABLES GROUP BY SCHEMA_NAME, TABLE_NAME, PART_ID ORDER BY SUM(MEMORY_SIZE_IN_TOTAL) DESC LIMIT 20;最后那条查大表的 SQL 非常实用。很多时候所谓的内存不足背后就是某张业务大表数据量暴增比如物料凭证、财务凭证或者是审计表、日志表。把大表找出来就可以判断是数据正常增长还是异常膨胀然后决定是否归档、分区、加内存。还有一个容易忽略的点会话session和语句statement级别的内存申请。如果有一条 SQL 查询了全表而没有加合适的过滤条件HANA 可能为这条查询分配巨大的排序内存。可以查M_ACTIVE_STATEMENTS和M_SESSION_MEMORY来定位这种“内存黑洞”。2.3 SUSE 专项检查sapconf、透明大页与 swap 状态SUSE 和普通的 RHEL/CentOS 不太一样它针对 SAP 场景提供了一套优化方案。所以拿到 SUSE 服务器我建议先确认几项基础配置是否到位。第一确认 sapconf 服务是否启用。SUSE 有个专门的包叫 sapconf它会把一系列针对 SAP 应用/HANA 的内核参数自动配置好比如 vm.swappiness、透明大页、NUMA 均衡等。检查方式systemctl status sapconf systemctl is-enabled sapconf如果服务没启用别急着手动改参数先把 sapconf 启用并生成配置再说。SUSE 的新版本里相关的服务也叫做 sapinstance 或 sapservices具体看版本。第二检查透明大页 THP 的状态。HANA 官方是不推荐开启 THP 的因为 HANA 对内存分配延迟敏感THP 可能导致内存分配卡顿和碎片化。执行一下cat /sys/kernel/mm/transparent_hugepage/enabled如果输出显示方括号在[always]上说明 THP 是开启的这就是一个隐患。理想状态应该是[madvise]或[never]。第三检查 swap 的配置。SAP HANA 对 swap 的态度比较微妙——它不希望 HANA 的数据页被换到 swap 上因为那会严重影响性能但在内存瞬间被占满时一点 swap 又没有会让内核更早触发 OOM。实际操作中大多数生产系统会配置一个“意思意思”的 swap比如 8GB 到 16GB并且把vm.swappiness调低比如 10。查看当前状态sysctl vm.swappiness swapon --show free -g3. 解决方案实操从应急恢复到根治调优3.1 应急恢复让 SAP 业务先跑起来的三种办法生产环境出了内存不足第一目标是“让业务赶紧恢复”而不是“优雅地分析问题”。根据故障严重程度我常用的应急手段有三个层次。第一个层次HANA 内部还活着只是内存紧张。这时候可以执行 HANA 自身的资源回收命令ALTER SYSTEM RECLAIM VIRTUAL MEMORY;这个命令会提示 HANA 把内部空闲的会话内存、堆内存整理一遍能归还给操作系统的部分就归还。实测中它能释放掉一部分“看似占用但实际空闲”的内存给系统腾出喘息空间。注意它不是银弹如果 HANA 真有大量数据驻留内存它释放不了太多。第二个层次HANA 内存池没爆但系统被其他进程占了内存。这时候不能重启 HANA 去陪绑而是找出系统里那些确实可以停掉的次要服务来释放内存。比如非关键的批量任务、监控 agent、临时启动的测试程序和业务方确认后停掉即可。第三个层次HANA 已经无法连接连 HANA Studio 都进不去。那就只能走计划内重启。重启之前尽量用sapcontrol强制收集一下当前系统信息记录日志路径方便事后分析sapcontrol -nr instance_number -function GetSystemUptime sapcontrol -nr instance_number -function StartSystem在这里必须强调不到万不得已不要直接 kill HANA 进程。HANA 是内存数据库直接 kill 会导致未持久化的数据丢失还可能带来数据恢复的漫长过程。即便要重启也要尽量走正常的sapcontrol -function StopSystem流程。3.2 核心调优修改 global.ini 限制 HANA 内存使用应急处理只解决眼前问题要想长时间不再复发最重要的一个动作是在 HANA 的配置文件里把内存上限明确设好。HANA 的配置核心是global.ini里面可以定义 HANA 内存管理器的行为。最关键的参数是global_allocation_limit它表示整个 HANA 实例允许从操作系统分配的内存上限单位是 MB。默认情况下HANA 会按物理内存的 90% 来自动设定这个值。问题就出在这个默认值上——如果这台服务器上还跑着 SAP 应用服务器、运维监控工具、数据库客户端等其他进程90% 这个比例显然太高了操作系统本身根本没有余量可用。我一般建议在内存充裕的专用服务器上把 HANA 的 global_allocation_limit 设为物理内存的 85% 左右如果这台机器同时跑其他服务就降到 70% 到 80%。比如物理内存 256GB 的机器HANA 上限设在 210GB 到 220GB 比较合理给操作系统和其他进程留出 30GB 以上的余量。设置方法有两种。一种是用 hdbnsutil 或直接改 ini 文件另一种是运行时动态修改不需要重启 HANAALTER SYSTEM ALTER CONFIGURATION (global.ini, SYSTEM) SET (memorymanager, global_allocation_limit) 220000 WITH RECONFIGURE;执行完可以再查一下是否生效SELECT * FROM M_MEMORY;看effective_limit字段如果显示 220000约 215GB说明生效了。这个方式最大的好处就是在线调整不用重启数据库生产环境也能用。除了总内存上限强烈建议顺手设置statement_memory_limit。它限制单条 SQL 语句最多能分配多少内存防止某个人写一条大烂 SQL 就把内存池抽干。这个参数同样在[memorymanager]段下面单位也是 MB。设置一个合理值比如总内存上限的 20%即 44GB 左右能有效阻止单条语句引发连锁故障。3.3 系统层加固内核参数和 SUSE 优化工具配置HANA 层面的参数设好了接下来要把 SUSE 操作系统本身的“坑”也填上。最核心的有四个动作。第一个动作启用 sapconf。SUSE 官方已经把 HANA 在内核层面的推荐参数打包进了 sapconf启用它相当于一键配置了 vm.swappiness、THP、NUMA 等一系列参数。在支持的版本上执行zypper install sapconf systemctl enable --now sapconf启用后可以查看sysctl -a | grep -E swappiness|max_map_count|numa_balancing|overcommit确认参数已经按推荐值生效。第二个动作永久禁用透明大页。之前的检查如果显示 THP 是 always那一定要干掉它。临时禁用可以执行echo never /sys/kernel/mm/transparent_hugepage/enabled但生产环境要的是重启后依然生效所以要把参数写进引导配置。修改/etc/default/grub在GRUB_CMDLINE_LINUX中加入transparent_hugepagenever然后重新生成 grub 配置grub2-mkconfig -o /boot/grub2/grub.cfg注意 SUSE 上有些版本是 UEFI 引导路径可能是/boot/efi/EFI/suse/grub.cfg要根据实际系统确认。改完需要重启才能确认最终生效。第三个动作调整 swapiness。SAP HANA 场景下不推荐把 swappiness 设为 0因为那会导致极端情况下内核不太愿意使用 swap反而更容易触发 OOM。设成 10 比较合理sysctl -w vm.swappiness10 echo vm.swappiness10 /etc/sysctl.d/99-sap-hana.conf第四个动作检查vm.max_map_count。HANA 运行时会创建大量内存映射区域如果这个值太低可能报内存相关错误。SAP 推荐值是 1000000sysctl -w vm.max_map_count1000000 echo vm.max_map_count1000000 /etc/sysctl.d/99-sap-hana.conf3.4 长期规划扩容、分层与监控告警如果确认 HANA 的数据量确实在快速膨胀而且业务发展迫切需要更多内存那就不是参数调优能解决的了要往更高层面做规划。第一是物理扩容。扩容之前用 HANA 自带的 sizing 工具或者看 M_CS_TABLES 的用量评估未来一年的增长趋势。内存扩容一定要预留余量别卡着业务当下需求的上限买。第二是数据分层HANA 有 Dynamic Tiering 和 Native Storage Extension 等功能可以把不常访问的老数据放到磁盘或列存扩展节点上。第三是数据归档从源头控制数据生命周期。很多企业的凭证表、日志表其实都是历史包袱定期归档到 Hadoop 或文件系统能回收大量内存。监控告警也很重要。生产环境一定要给内存使用率做好监控不管是用 Prometheus Grafana、Zabbix 还是 SAP Solution Manager规则可以简单点HANA 实例内存使用率超过 85% 就告警超过 90% 就通知应急小组。要留出足够的时间窗口去处理而不是每次都被动等到业务瘫痪才介入。4. 常见问题与排查技巧实录实战中的坑与解药4.1 OOM Killer 为什么会杀死 HANA 进程这是最让人头疼的场景之一。系统日志里看到 HANA 进程被 OOM Killer 终止整个 SAP 应用直接不可用。OOM Killer 选进程的依据是 oom_score这个分数跟进程的物理内存占用量正相关。HANA 作为一台机器上最大的内存消费者几乎必然排在 OOM 击杀名单的榜首。要避免 HANA 被杀核心思路是“让它不那么容易被选中”和“别让系统走到 OOM 那一步”。前者可以手动微调 oom_score_adj给 HANA 进程设置一个负分降低被杀概率echo -800 /proc/HANA_PID/oom_score_adj但这种方法治标不治本而且进程重启后需要重新设置。我更推荐把功夫花在预防上设置合理的 global_allocation_limit、留足系统空闲内存、配置好监控让系统根本走不到 OOM 那一步。真要走到 OOM说明内存规划确实出了问题加内存或者优化数据模型是正道。4.2 HANA 参数改了不生效的排查思路很多人设置了 global_allocation_limit之后查 M_MEMORY 却发现 effective_limit 还是老样子。这个问题我排查过很多次大概率是下面几个原因。第一个原因是改错了 scope。ALTER SYSTEM ALTER CONFIGURATION有 SYSTEM 和 DATABASE 两种作用范围如果只在某个租户库的 DATABASE 范围内修改整个实例未必会采用。排查时先确认命令里用的是SYSTEM。第二个原因是参数名写错。比如[memorymanager] global_allocation_limit是在 memorymanager 段下面的有些人把它写进了[database]段自然不生效。可以用下面这句检查当前配置实际落在哪个层SELECT * FROM M_CONFIGURATION WHERE KEYglobal_allocation_limit;第三个原因是压根没触发 reload。虽然命令带了WITH RECONFIGURE但有些版本的 HANA 对特定参数要求重启实例。如果在线修改后确认没生效而配置已经写入了 ini 文件那就在维护窗口重启一次 HANA 实例通常能解决。4.3 HANA 内存一直涨不下来的原因有的系统明明没有大查询、没有大量数据写入但 HANA 内存占用就是稳步上升几天之后又逼近上限。这种情况常见原因有三类。一类是会话堆积比如应用服务器的连接池没有正常释放会话导致 HANA 里面一堆 idle 会话挂着每个会话占一点内存多了就吓人。可以查M_SESSION_MEMORY和M_CONNECTIONS找出那些长时间 inactive 但仍在占用内存的连接在应用层调整连接池参数。另一类是堆内存碎片化。HANA 长期运行之后内存池里的碎片越来越多新的内存申请得不到连续空间它就向 OS 再申请。应对办法是在维护窗口执行ALTER SYSTEM RECLAIM VIRTUAL MEMORY然后重启实例让堆内存彻底整理。第三类是统计信息或数据模型的问题比如某张表频繁删除插入delta store 越来越大导致列式存储的内存占用超过预期。这类需要通过数据压缩、分区整理来缓解。4.4 硬件升级后内存仍不足的“玄学”之前有个客户把服务器物理内存从 128GB 升到 256GB结果 HANA 内存还是报警。我上去一看就明白了——global_allocation_limit 还是按旧的物理内存算出来的那个值甚至可能是手工配的死值一直没跟上新硬件。HANA 的默认限制只在安装时或重启时评估物理内存如果你手工设置过它不会有任何变化。升级内存后第一件事就是用 SQL 把 M_MEMORY 看一遍确认 effective_limit 是否符合预期。如果还是旧值可以动态重设比如直接重跑一次ALTER SYSTEM ALTER CONFIGURATION把 global_allocation_limit 调整到新物理内存的 85%。4.5 避坑速查表为了方便排查我把常见的症状、原因和应对放在一起做个速查表遇到问题可以直接对照。现象根因处理建议系统 free 内存低但 HANA 还能用page cache 被压缩系统可用内存偏少关注 available调整 HANA 内存上限给系统留余量HANA 进程被 OOM Killer 杀掉系统物理内存完全耗尽设置合理 global_allocation_limit调整 oom_score_adjHANA 内存使用率持续逼近 90%数据增长、会话堆积或内存碎片查大表和会话RECLAIM 内存归档、扩容修改 global.ini 不生效scope 错误、参数名错误或需重启查 M_CONFIGURATION用 SYSTEM scope维护窗口重启系统频繁 swap 且性能暴跌swappiness 过高或未配置 sapconf启用 sapconf设置 vm.swappiness10查询报表偶尔超时透明大页开启内存碎片化禁用 THP重启生效结尾的实操心得这东西碰得多了我现在处理 SUSE SAP HANA 内存问题的思路已经固定下来了先看 available、再看 HANA 内部、然后调 global_allocation_limit、最后查系统内核参数。按这个顺序一般问题都能在半小时内定位。最后再分享一个小技巧我会在每次硬件扩容或 HANA 版本升级后主动检查一次 M_MEMORY 视图和相关内核参数不要等服务告警了才想起来。内存问题最好的解法永远是“留有余量、提前发现”等你看到 SAP 应用连不上的时候任何一个操作都意味着业务已经在损失了。