oracle oom,OOM 导致数据库重启

本文详细描述了一次Oracle RAC数据库因OOM导致的自动重启问题。通过分析alert日志、系统日志和trace文件,确定是由于数据库写进程DBW4被Linux OOM killer杀死,原因是内存耗尽。分析还涉及DBW4进程的内存使用情况和全局缓存服务(GCS)。解决方案主要针对GC等待事件和SQL优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境描述

选项

信息

系统类型

Linux x86 64-bit

系统内核

3.10.0-957.el7.x86_64

数据库版本

19.7.0.0.0

内存

500G

CPUs

128

架构

RAC

问题描述

数据库二节点经常性的自动重启

第一层分析:自动重启的原因

数据库重启,一般都是先看alert日志,有如下显示

2020-07-16T16:59:10.896311+08:00

System state dump requested by (instance=2, osid=124268 (PMON)), summary=[abnormal instance termination]. error - 'Instance is terminating.'

System State dumped to trace file /oracle/diag/rdbms/loandb/loandb2/trace/loandb2_diag_124290.trc

2020-07-16T16:59:10.918179+08:00

PMON (ospid: 124268): terminating the instance due to ORA error 471

2020-07-16T16:59:10.922909+08:00

Cause - 'Instance is being terminated due to fatal process death (pid: 76, ospid: 124440, DBW4)'

2020-07-16T16:59:20.408801+08:00

Termination issued to instance processes. Waiting for the processes to exit, wait time 5 sec

2020-07-16T16:59:20.704260+08:00

ORA-1092 : opitsk aborting process

2020-07-16T16:59:24.413038+08:00

Instance terminated by PMON, pid = 124268

2020-07-16T16:59:28.427812+0

<think>好的,用户现在的问题是红帽系统的缓存满了,里面全是Oracle的进程,想要清理缓存。首先,我需要理解用户的具体情况。他说缓存满了,可能是指系统的内存被大量占用,导致性能问题。而里面全是Oracle进程,可能是指Oracle数据库占用了大量的内存,或者系统的缓存(比如buffer/cache)被Oracle进程占用,导致其他应用程序无法获得足够的内存。 首先,我需要回忆Linux系统内存管理的知识。在Linux系统中,内存使用包括几个部分:已使用的内存、空闲内存、buffer和cache。Buffer是用于块设备的缓冲,而cache是文件系统的缓存。这些缓存可以被自动释放,当系统需要更多内存时,内核会自动回收这些缓存。但用户可能看到buffer/cache占用过高,担心影响性能,所以想要手动清理。 接下来,用户提到系统中全是Oracle的进程,这可能意味着Oracle数据库是主要的内存占用者。Oracle数据库本身会使用大量内存,尤其是SGA(System Global Area)和PGA(Program Global Area),这些是Oracle为了性能优化而预先分配的内存区域。如果配置不当,可能会占用过多内存,导致系统内存不足。 用户的问题是如何清理缓存。这里需要考虑几个方面:手动释放系统缓存、调整Oracle的内存配置、以及优化系统或数据库以避免未来再次出现这种情况。 首先,手动释放系统缓存的方法。在Linux中,可以通过写入特定的值到/proc/sys/vm/drop_caches来释放缓存。例如: echo 1 > /proc/sys/vm/drop_caches # 释放页缓存 echo 2 > /proc/sys/vm/drop_caches # 释放dentries和inode缓存 echo 3 > /proc/sys/vm/drop_caches # 释放所有缓存 不过需要注意,直接释放缓存可能会影响系统性能,尤其是在高负载时,因为缓存的存在是为了加速磁盘访问。因此,最好在必要时才这样做,并且要确保不会影响到正在运行的服务。 接下来,检查Oracle进程的内存使用情况。用户需要确认是Oracle的哪些进程占用了大量内存,是否存在内存泄漏或者配置不当。可以使用top或ps命令查看进程的内存占用情况,或者使用pmap查看具体进程的内存映射。例如: top -p 7800 ps aux | grep oracle pmap -x 7800 | tail -n 1 如果发现某个Oracle进程占用了异常多的内存,可能需要调整其内存参数,比如SGA和PGA的大小。在Oracle数据库中,SGA_MAX_SIZE和SGA_TARGET参数控制SGA的大小,而PGA_AGGREGATE_TARGET控制PGA的总大小。用户可以通过SQL*Plus连接到数据库,查看并调整这些参数: SQL> show parameter sga; SQL> alter system set sga_max_size=... scope=spfile; SQL> alter system set pga_aggregate_target=... scope=spfile; 调整后需要重启数据库实例才能生效。需要注意的是,调整这些参数需要谨慎,避免设置过小影响数据库性能,或者过大导致系统内存不足。 另外,用户可能没有正确配置HugePages,导致Oracle使用标准内存页,增加了管理开销。配置HugePages可以减少内存页的数量,提高性能并减少内存碎片。需要根据系统内存和Oracle的需求计算合适的HugePages数量,并在/etc/sysctl.conf和/etc/security/limits.conf中进行配置。 此外,检查是否有不需要的Oracle进程在运行,比如遗留的会话或后台进程。可以使用Oracle的工具如Enterprise Manager或手动查询V$SESSION视图来识别并终止不必要的会话。 用户可能还需要考虑系统的交换空间(swap)。如果物理内存不足,系统会使用swap空间,但这会导致性能下降。通过free -h命令查看内存和swap使用情况,如果swap使用过高,可能需要增加物理内存或优化应用内存使用。 另外,定期重启Oracle服务或系统可以临时释放内存,但这不是长久之计。应该找到根本原因,比如内存泄漏或配置问题,进行修复。 总结来说,用户的问题需要分步骤处理:首先确认内存使用情况,手动释放缓存(谨慎操作),调整Oracle内存配置,优化系统参数,检查不必要的进程,并考虑增加物理内存或配置HugePages。同时,要确保操作不会影响数据库的正常运行,避免数据丢失或服务中断。</think>在 Red Hat 系统中,若发现缓存(Buffer/Cache)被 Oracle 进程占满,导致系统资源紧张,可以通过以下步骤清理缓存并优化内存使用: --- ### **一、确认内存占用情况** 1. **查看内存整体使用**: ```bash free -h ``` - 关注 `buff/cache` 列,确认缓存是否过高。 - 示例输出: ``` total used free shared buff/cache available Mem: 62G 20G 2.0G 1.2G 40G 39G Swap: 4.0G 0B 4.0G ``` 2. **定位 Oracle 进程的内存占用**: ```bash top -p $(pgrep -f "ora_") # 查看 Oracle 进程的实时内存使用 ps aux | grep oracle # 检查所有 Oracle 相关进程 ``` --- ### **二、手动清理系统缓存** 1. **释放 PageCache、dentries 和 inodes**: ```bash # 执行前确保无关键操作(可能短暂影响性能) sync # 确保数据写入磁盘 echo 3 > /proc/sys/vm/drop_caches ``` - **注意**:此操作释放的是系统缓存(非 Oracle 进程占用的内存),仅临时缓解问题。 2. **验证缓存释放效果**: ```bash free -h # 观察 buff/cache 是否减少 ``` --- ### **三、优化 Oracle 内存占用** Oracle 默认会预分配大量内存(SGA/PGA),需调整配置避免过度占用。 1. **检查当前内存配置**: ```sql -- 登录 sqlplus SQL> show parameter sga_target; SQL> show parameter pga_aggregate_target; SQL> show parameter memory_target; ``` 2. **调整内存参数**: - 修改 `SGA_TARGET` 和 `PGA_AGGREGATE_TARGET`,避免总和超过物理内存的 60%(需根据系统总内存调整): ```sql ALTER SYSTEM SET sga_target=12G SCOPE=spfile; ALTER SYSTEM SET pga_aggregate_target=4G SCOPE=spfile; ``` - 重启数据库生效: ```bash sqlplus / as sysdba SQL> shutdown immediate; SQL> startup; ``` 3. **启用 HugePages**(减少内存碎片和管理开销): - 计算 HugePages 数量: ```bash # 根据 SGA 大小计算(单位 MB) grep Hugepagesize /proc/meminfo awk '/^MemTotal/ {print int(($2/1024 * 0.8)/2)}' /proc/meminfo ``` - 配置 `/etc/sysctl.conf`: ```bash vm.nr_hugepages = 计算值 ``` - 重启生效: ```bash sysctl -p ``` --- ### **四、清理 Oracle 内部缓存** 1. **释放 Buffer Cache**(谨慎操作,可能影响性能): ```sql -- 清空 Buffer Cache ALTER SYSTEM FLUSH BUFFER_CACHE; ``` 2. **清理共享池和游标缓存**: ```sql ALTER SYSTEM FLUSH SHARED_POOL; ALTER SYSTEM FLUSH GLOBAL CONTEXT; ``` --- ### **五、长期优化建议** 1. **限制 Oracle 进程数**: - 检查 `DB_WRITER_PROCESSES` 等参数,避免过多后台进程: ```sql SQL> show parameter db_writer_processes; ``` 2. **监控内存泄漏**: - 使用 `pmap` 或 `valgrind` 检查异常内存占用: ```bash pmap -x <Oracle_PID> | tail -n 1 # 查看进程总内存 ``` 3. **启用自动内存管理(AMM)**: - 设置 `MEMORY_TARGET` 和 `MEMORY_MAX_TARGET`,让 Oracle 自动分配 SGA 和 PGA: ```sql ALTER SYSTEM SET memory_target=16G SCOPE=spfile; ``` 4. **定期维护**: - 清理无效会话和长时间空闲连接: ```sql SELECT sid, serial# FROM v$session WHERE status='INACTIVE'; ALTER SYSTEM KILL SESSION 'sid,serial#'; ``` --- ### **六、关键注意事项** 1. **避免直接 Kill 进程**: - 强制终止 Oracle 进程可能导致数据损坏,优先通过 SQL 命令或 `srvctl` 停止服务。 2. **保留 Swap 空间**: - 确保 Swap 空间足够(至少 4GB),防止内存耗尽触发 OOM Killer。 3. **日志分析**: - 检查 `/var/log/messages` 和 Oracle 的 `alert.log`,排查内存泄漏或异常错误。 --- 通过以上步骤,可有效清理系统缓存并优化 Oracle 内存使用。若问题持续,建议联系 DBA 或系统管理员深入分析内存分配策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值