首页 文章 精选 留言 我的

精选列表

搜索[应急响应服务],共10028篇文章
优秀的个人博客,低调大师

CentOS7设置SWAP分区,小内存服务器的救世主

前言 Swap分区在系统的物理内存(这里应该是运行内存)不够用的时候,把物理内存中的一部分空间释放出来,以供当前运行的程序使用。那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap分区中,等到那些程序要运行时,再从Swap分区中恢复保存的数据到内存中。 设置 1.添加SWAP分区 sh 复制代码 cd / && dd if=/dev/zero of=swapfile bs=1024 count=4194304 chmod 600 /swapfile && mkswap /swapfile swapon /swapfile && swapon -s echo "/swapfile swap swap defaults 0 0" >> /etc/fstab 注: count=4194304中4194304为交换分区大小 4194304=102410244大小为4G 交换区大小设置有个参考依据,物理内存小于4G则SWAP设置为物理内存的两倍、物理内存等于4G则SWAP设置为4G、物理内存大于4G则SWAP设置为物理内存的1/2。 2.重启系统 sh 复制代码 shutdown -r now 3.查看分区结果 sh 复制代码 free -m 4.关闭交换空间 sh 复制代码 cd / && swapoff swapfile && rm -rf swapfile

优秀的个人博客,低调大师

PGA 超限的一次应急处置:扩容、清游标、杀会话

9 月 30 号这一天,接到反馈,业务反应查询有点慢。数据库显示acknowledge over PGA limit是最严重的等待事件。 这套库是 Oracle 19c 的 CDB,挂着 12 个 PDB,宿主机 24 核、94.4G 内存,SGA 已经占掉 58G。 --- ## 一、上午:AWR中最扎眼的是等待事件 AWR显示: |指标|值| | --- | --- | |DB Time|4,210.78 分钟(快照区间 60 分钟)| |会话数|393 → 539| |每秒 DB Time|69.9 秒| 一小时里累计 DB Time 四千多分钟,等于平均每秒有 70 个会话在忙。24 个核的机器干出这个数,说明大部分会话没在跑,是在等。 再看 Top 等待事件,第一行就把方向给定了: ``` acknowledge over PGA limit 3,616,348 次 172.2K 秒 68.2% cursor: mutex X 1,464,929 次 50.5K 秒 20.0% cursor: mutex S 451,284 次 1,446.9 秒 0.6% cursor: pin S wait on X 1,112 次 4,504.4 秒 1.8% resmgr:cpu quantum 4,563 次 2,326.9 秒 0.9% DB CPU 13.5K 秒 5.4% ``` 六成八的 DB Time 花在一个叫 `acknowledge over PGA limit` 的等待上。这个等待不属于 User I/O,也不属于 Concurrency,它被归类在 Scheduler 下面。含义是:进程申请的内存超过了 `pga_aggregate_limit`,Resource Manager 把会话挂起来排队,等有人把内存让出来。 换句话说,`PGA` 已经不是"紧张",是溢出了。 拉到内存小节,数字对得上: |指标|Begin|End| | --- | --- | --- | |Host Mem|96,667.8 MB|96,667.8 MB| |SGA use|59,392.0 MB|59,392.0 MB| |PGA use|32,961.6 MB|40,483.8 MB| |SGA+PGA 占主机内存|95.54%|103.32%| 当时的参数是 `pga_aggregate_target=8G`、`pga_aggregate_limit=16G`。实际分配到 40.5G,硬限制 16G,超了 1.5 倍还多。 操作系统那边也印证了:`FREE_MEMORY_BYTES` 只剩 505 MB,`LOAD` 从 9 走到 10,`RSRC_MGR_CPU_WAIT_TIME` 累计 250,813。 ADDM 的结论跟我们的判断一致,它把三条 finding 按活跃会话占比列了出来: ``` Top SQL Statements AAS 93.07 75.14% PGA_AGGREGATE_LIMIT Throttling AAS 93.07 66.40% Shared Pool Latches AAS 93.07 25.08% ``` ``` 有意思的是这三条的平均活跃会话数都是 93.07。同一批会话同时满足三个条件,说明它们是被同一件事卡住的。 --- ## 二、20% 的 `cursor: mutex X` 是怎么来的 排在 PGA 后面的是 `cursor: mutex X`,占了 20%,五十多K 秒。这个等待通常指向 shared pool 里某个父游标下的子游标太多,会话遍历的时候抢互斥 latch。 顺着这条线往 Top SQL 里找,结果很集中: |指标|c1sj9us39v7nx|全库第二| | --- | --- | --- | |Elapsed Time|112,600.21 秒|20,664.08 秒| |占 DB Time|44.57%|8.18%| |Sharable Memory|326,189,368 B(311 MB)|55,363,512 B| 一条 SQL 吃掉 44.57% 的 DB Time,在 shared pool 里占了 311 MB,是第二名的六倍。 再看最底下的 `SQL ordered by Version Count`: ``` c1sj9us39v7nx version_count = 5,481 BSSC gh42bgwdn0by6 version_count = 926 OMC 5cu0x10yu88sw version_count = 569 OPM ``` ``` **五千四百八十一个子游标。** 第二名才 926。 具体的SQL这里不方便展示,是一条查用户角色权限的普通查询。 --- ## 三、下午:好了大半,没有好透 中间我们把 PGA 参数调了上去,也把这条 SQL 的父游标清了。到下午 15 点到 16 点这一小时再采样,DB Time 从 4,210.78 分钟降到 **681.86 分钟,降了 83.8%**。 先看结果如何,把两份报告的头号指标列在一起: |指标|上午|下午| | --- | --- | --- | |DB Time|4,210.78 分钟|681.86 分钟| |每秒 DB Time|69.9 秒|11.5 秒| |会话数|393 → 539|501 → 513| |每秒事务数|14.6|37.0| |每秒逻辑读|320,926.3 块|272,034.2 块| |每秒物理读|27,441.6 块|31,852.2 块| |LOAD|9 → 10|12 → 5| |RSRC_MGR_CPU_WAIT_TIME|250,813|153| 这里有个必须先讲清楚的前提:**下午的业务量是涨的。** 每秒事务数从 14.6 涨到 37.0,翻了两倍半;物理读也涨了 16%。在业务量涨上去的同时 DB Time 降了 83.8%,这样才谈得上是真改善,排除了"没人用所以变快"这种假象。 等待事件的变化更能说明问题: |等待事件|上午|下午| | --- | --- | --- | |cursor: mutex X|1,464,929 次 / 50.5K 秒 / 20.0%|完全消失| |cursor: mutex S|451,284 次 / 1,446.9 秒 / 0.6%|完全消失| |resmgr:cpu quantum|4,563 次 / 2,326.9 秒 / 0.9%|完全消失| |cursor: pin S wait on X|1,112 次 / 4,504.4 秒 / 1.8%|183 次 / 29.2 秒 / 0.1%| |DB CPU|13.5K 秒 / 5.4%|7,945.4 秒 / 19.4%| |db file sequential read|4,811.7 秒 / 1.9%|3,299.3 秒 / 8.1%| 三个 concurrency 类等待归零,配合 `RSRC_MGR_CPU_WAIT_TIME` 从 250,813 掉到 153(降了 99.9%),系统级数据也跟着变了——`LOAD` 从 12 掉到 5,CPU 资源管理器不再需要限流。 那条 SQL 的表现同样明显: |指标|上午|下午| | --- | --- | --- | |Elapsed Time|112,600.21 秒(第 1 名,44.57%)|992.09 秒(第 6 名,2.42%)| |Sharable Memory|326,189,368 B(榜首)|退出榜单| 榜首位置让给了 `6a0cn0u0ayk2f`(3,561 秒,8.70%),那是一条正常的高频小 SQL,45 万次执行、单次 0.01 秒,属于健康形态。 --- ## 四、但 `acknowledge over PGA limit` 还是第一名 这是下午那份报告里最刺眼的地方。 ||上午|下午| | --- | --- | --- | |acknowledge over PGA limit|3,616,348 次 / 172.2K 秒 / 68.2%|1,483,218 次 / 26.4K 秒 / 64.6%| 等待次数降了 59%,总时长从 172.2K 秒降到 26.4K 秒,降幅不小。但**占 DB Time 的比例几乎没动**,从 68.2% 到 64.6%,还是稳稳的第一。 ADDM 在下午那份报告里,依然把同一条 finding 排在最前面: ``` PGA_AGGREGATE_LIMIT Throttling AAS 12.80 66.40% PGA_AGGREGATE_LIMIT Throttling AAS 10.20 62.18% Top SQL Statements AAS 12.80 26.50% ``` ``` 两份报告、四个 ADDM task,`PGA_AGGREGATE_LIMIT Throttling` 的占比一直在 62% 到 72% 之间浮动。比例纹丝不动意味着:在下午这个采样区间里,内存依然是第一瓶颈,只是同时排队的人变少了。 下午的参数已经提到 `pga_aggregate_target=12G`、`pga_aggregate_limit=24G`。但内存小节给出的实际用量是: |指标|上午 End|下午 End| | --- | --- | --- | |PGA use|40,483.8 MB|33,130.6 MB| |SGA+PGA 占主机内存|103.32%|95.71%| **33 GB 的实际用量,对上 24 GB 的硬限制,还是超的。** 加上前面业务量涨了两倍半,能维持在 33 GB 不继续往上跳水,已经算是调度器勉强撑住了。 另外要提一句:下午这份报告的采样区间是 15:00 到 16:00,那时候会话还没清干净。真正彻底平稳,是后来把堵住的会话全部杀掉、应用重连之后的事。 --- ## 五、中间那条线:五千多个子游标是怎么查出来的 回到上午报告的 5,481。查这五千多个子游标的成因,前后绕了三次。 ### 5.1 第一次:以为没用绑定变量 看到五千多个子游标,第一反应是硬编码字面量。但 SQL 原文摆在上面,谓词写的是: ``` AND u.ID = :1 ``` 用了绑定变量,而且只有一个。这个判断当场作废。 ### 5.2 第二次:教科书里的 Bind Graduation,被打脸 既然用了绑定变量,最常见的解释是绑定变量长度毕业(Bind Graduation)——不同长度的绑定值各衍生一个子游标。 把 5,171 行 `v$sql_bind_capture` 拉出来做统计: |列|取值|行数|占比| | --- | --- | --- | --- | |POSITION|1|5,171|100%| |DATATYPE_STRING|NUMBER|5,171|100%| |MAX_LENGTH|22|5,171|100%| |CHARACTER_SID|852|5,171|100%| 四项全部零变异。两个假设一起排掉。 ### 5.3 第三次:信了 REASON,被 Y/N 列掀翻 `v$sql_shared_cursor` 里有一列 REASON,是给人看的 XML 汇总文本。导出来是这个分布: |REASON 里的 ID|reason 文本|子游标数|占比| | --- | --- | --- | --- | |3|Optimizer mismatch|2,966|57.4%| |39|Bind mismatch|2,205|42.6%| 跟着这个分布做了一堆分析:转移矩阵、游程检验、时序先后……得出"两个独立机制随机交替、乘法效应产生六千多个组合"的结论,看着相当自洽。 然后去查同一张表里的 Y/N 标志列: ``` SELECT optimizer_mismatch, bind_mismatch, bind_uacs_diff, bind_equiv_failure, COUNT(*) AS cnt FROM v$sql_shared_cursor WHERE sql_id = 'c1sj9us39v7nx' GROUP BY optimizer_mismatch, bind_mismatch, bind_uacs_diff, bind_equiv_failure ORDER BY cnt DESC; ``` 结果是: ``` N N N Y 5162 Y N N Y 9 ``` ``` `BIND_EQUIV_FAILURE='Y'` 覆盖了全部 5,171 个子游标,一条例外都没有。把两种判据放在一起对比: |判据|REASON 说|Y/N 列实际|偏差| | --- | --- | --- | --- | |Optimizer mismatch|2,966|9|差 329 倍| |Bind mismatch|2,205|0|根本不存在| |Bind Equiv Failure|0|5,171|完全颠倒| 最后一行最要命。正是因为 REASON 说 Bind Equiv Failure 计数为零,才在前面把 ACS 排除掉的。**REASON 把占 100% 的真凶整个漏报了。** ### 5.4 清完之后的意外收获:错配原因翻了过来 父游标清完之后,下午又查了一次同一张表。这次只有 36 行,做汇总统计: ``` OPTIMIZER_MISMATCH 35 BIND_MISMATCH 0 BIND_PEEK_MISMATCH 0 BIND_EQUIV_FAILURE 34 LANGUAGE_MISMATCH 0 EDITION_MISMATCH 0 ``` ``` 把前后对照起来看,变化相当明显: ||清理前|清理后| | --- | --- | --- | |BIND_EQUIV_FAILURE='Y'|5,171 / 5,171(100%)|34 / 36(94%)| |OPTIMIZER_MISMATCH='Y'|9 / 5,171(0.2%)|35 / 35(100%)| 清理之前 ACS 几乎包揽了全部;清理之后 OPTIMIZER_MISMATCH 升到了 100%。 逐行展开看更清楚。新批次的 child 编号是 0 到 36,其中: ``` child 0, 2 OM=Y BEF=N child 3~17, 19~30, 34 OM=Y BEF=Y child 31, 32, 33, 35, 36 OM=Y BEF=Y ROLL_INVALID=Y child 5516 OM=N BEF=Y ROLL_INVALID=Y ← 老批次残留 ``` ``` **这里有一个决定性的细节:child 0 和 child 2 是 ****`OPTIMIZER_MISMATCH='Y'**`** 而 ****`BIND_EQUIV_FAILURE='N'**`**。** 这说明光靠优化器环境差异,就足以铸造出一个新子游标,**ACS 并不是必要条件**。之前把 ACS 当主因、把 Optimizer mismatch 当次要命中,方向是反的。正确的因果顺序应该是: ``` 会话之间的优化器环境不一致(上游) → 铸造出一批多余 child → 这些 child 各自进入 bind-aware 状态 → ACS 再按选择性差异做乘数放大 → 从几十个涨到几千个 ``` ``` ACS 是放大器,不是发动机。真正该盯的是优化器环境为什么在不同会话之间会变。 这 36 行里还有两条线索。一是 child 31、32、33、35、36 带着 `ROLL_INVALID_MISMATCH`,这是统计信息失效留下的印记,说明期间有 `DBMS_STATS` 作业在跑,把刚建好的游标又作废了一遍。二是 child 编号 0 到 36 之间缺了 1 和 18,新批次刚生成就淘汰了两个,说明新建出来的 child 照样没人复用,只是渗漏的速度慢下来了。 至于 child 5516,它保留着老批次的签名(`OM=N` / `BEF=Y`),在计入 `version_count` 时被排除在外,所以会看到 36 行、`version_count` 却是 35 这个现象。 --- ## 六、实际上的处置过程 我同步展开了看看AI怎么回答。AI做着做着就开始说有bug要打补丁什么的。 我给他的边界很明确:不打补丁、不改优化器参数。不能有个什么事情就补丁,或许在有些公司可以。但是我们这里绝对不允许。 ### 6.1 第一步:把 PGA 加上去 这一步是对着占 68.2% 的那个等待去的,先解决"会话全被挂起"这个紧急状态: ``` ALTER SYSTEM SET pga_aggregate_target = 12G SCOPE=BOTH; -- 原 8G ALTER SYSTEM SET pga_aggregate_limit = 24G SCOPE=BOTH; -- 原 16G ``` 从 40.5 GB 的实际分配量看,16 GB 的 limit 确实是被击穿了的。这一步做完,DB Time 下来了,`cursor: mutex X` 跟着归零。但正如第四节所说,下午那份报告里 PGA 等待还是第一。 ### 6.2 第二步:清父游标 ``` SELECT address || ',' || hash_value AS cursor_key, version_count FROM v$sqlarea WHERE sql_id = 'c1sj9us39v7nx'; EXEC sys.dbms_shared_pool.purge('00000006645E4B18,110993053', 'C'); ``` 效果:`version_count` 从五千多条降到 **35**,降幅 99.3%。那个占着 311 MB 的游标也退出了 Sharable Memory 榜。 同批查出来的另外三条 SQL,量级都很正常,正好衬托出只有这一条异常: |sql_id|version_count| | --- | --- | |208qcat309zag|3| |2jb4jnvk2avr0|3| |9faby2nj5mw68|7| |c1sj9us39v7nx|35(清理前 5,000+)| 这里必须强调一句:**千万不要用 ****`ALTER SYSTEM FLUSH SHARED_POOL**`**。** 那会把全实例所有游标清干净,业务高峰期等同于自杀。用 `DBMS_SHARED_POOL.PURGE` 定向清这一条才对。 还有一点说明:下午那份 AWR 里 `SQL ordered by Version Count` 显示的还是 5,271,看着像"一小时又长回去了"。后来在 16:43 实测确认是 35,再结合新批次 child 编号是 0 到 36 连续排列,能判定那 5,271 是**老游标被标记失效后还没完全回收的残留计数**,不是重新涨起来的。 ### 6.3 第三步:杀会话 cleanup 之后仍没彻底恢复,把持有该游标的会话批量杀掉,应用重连,才真正平稳下来。 这一步不是多余。`DBMS_SHARED_POOL.PURGE` 在目标游标被会话持有时会**静默失败**——不报错,但也没效果。很多人 purge 完发现"没用",基本都卡在这里。 另外,`pga_aggregate_limit` 的行为是优先"挂起+杀掉 PGA 用量最大的会话",而不是直接让整个实例崩。所以当限制被击穿之后,会有一批会话陷入长时间的排队状态。不清掉它们,`pga_aggregate_limit` 调得再大也缓不过来——下午那份报告里 PGA 等待仍占 64.6%,很大程度就是这个原因。 --- ## 七、复盘:三件事各解决了什么 **第一步加 PGA**,让 `resmgr:cpu quantum` 消失、`RSRC_MGR_CPU_WAIT_TIME` 降 99.9%、`LOAD` 从 12 掉到 5。这一步解决的是"CPU 资源管理器在限流",代价是内存水位维持在 33 GB 高位。它止住了血,但没有消除 `acknowledge over PGA limit`。 **第二步清父游标**,让三个 concurrency 类等待归零,那条 SQL 从占 44.57% 掉到 2.42%。这一步解决的是 shared pool 里的遍历竞争和 311 MB 的内存占用。 **第三步杀会话**,才是让 PGA 等待彻底退下去的最后一块拼图。 三者有先后,缺了任何一步都不完整。尤其是第三步,容易被当成"前两步没做干净"的补救动作,实际上它是必须的。 ---

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

用户登录
用户注册