拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

YashanDB 一把定位引起SWAP空间异常的会话和SQL语句

YashanDB 一把定位引起SWAP空间异常的会话和SQL语句 我们的文章会在微信公众号IT民工的龙马人生和博客网站 ( www.htz.pw )同步更新 欢迎关注收藏也欢迎大家转载但是请在文章开始地方标注文章出处谢谢由于博客中有大量代码通过页面浏览效果更佳。YashanDB 一把定位引起SWAP空间异常的会话和SQL语句摘要在 Oracle 运维时TEMP 被打爆、排序/哈希往外换路径几乎不用想。到了 YashanDBTEMP 表空间还在但 VM 中间结果换出主要落在SWAP关键参数也变成以VM_BUFFER_SIZE为代表的一套——不能再用 PGA TEMP 的老地图硬套。SWAP 水位往上走或会话卡在swapping * vm block业务侧往往就是突然变慢。这时不必先手写拼V$VM/V$VMSTAT那一串先ytop -f swap.sql把参数、页、水位、段和会话收齐抄到 sql_id 再ytop -f sql.sql看文本和计划。文中两例都在 23.5.2.101 上压过临时 LOB以及 HASH JOIN 把vm_buffer打穿。第二例里段类型有时会显示成Unknown别只盯着手册上的字面量HASH。1. 在 Oracle 运维时TEMP 几乎是肌肉记忆大排序ORDER BY/GROUP BY、哈希连接溢出、建索引排序、部分物化中间结果放不下 PGA就会落到TEMP。值班常见路径是dba_temp_free_space、v$tempseg_usage、v$sort_usage再追到会话和 SQL调参也绕不开 PGA 和 TEMP 文件——通常先点名 SQL再谈加 TEMP。做 YashanDB 时这套直觉还在只是落盘的主战场换了名字和参数。2. YashanDB还有 TEMP主力却是 SWAP看dba_temp_free_space多数实例里TEMP和SWAP都会在名称在 YashanDB 里大致干什么别和谁搞混TEMP 表空间仍保留部分临时对象/路径会用到不要默认“和 Oracle TEMP 一一对应、扛全部溢出”SWAP 表空间VM虚拟内存机制在vm_buffer不够时的磁盘换出区Linuxswap分区/文件VM /vm_buffer排序、HASH、物化、临时 LOB 等中间结果优先吃的内存DATA_BUFFER_SIZE、OS 虚拟内存总称关键参数常见盯VM_BUFFER_SIZE以及版本手册里的相关 VM 参数不要照搬 Oracle 的PGA_AGGREGATE_TARGET心智直接套结构上可以看成中间结果VM ├─ vm_buffer内存优先 └─ SWAP 表空间buffer 不够再换出SWAP 水位涨、会话卡在swapping * vm block体感和当年 TEMP 被打爆差不多只是对象变成了 SWAP 和 VM 相关视图。OS 内存和磁盘 IO 可以对照看但库内 SWAP 换出不等于操作系统 swap 在用。3. 哪些场景会吃 SWAP优先怎么处理常见会把 VM 顶高、再打到 SWAP 的场景和当年 TEMP 压力来源差不多大数据量ORDER BY/ 多级排序、缺过滤或排序列吃不到索引。大数据量HASH JOIN建哈希表溢出。统计信息收集采样与中间结果尤其挤在业务高峰。建/重建索引时的键排序。执行算子物化复杂 SQL、多阶段、大结果集。临时 LOB拼接/转换、DBMS_LOB.CREATETEMPORARY、表达式产生的 TempLOBNOCACHE更容易往 SWAP 的LOB_DATA落。VM/SWAP 高不等于一定是内存参数配错也可能是计划差、高峰撞车、临时 LOB 没释放、或中间结果本身就大。处理时建议先软后硬先后做什么说明1优化 SQL / 错峰减排序与 HASH 规模大统计、建索引、批量 LOB 避开高峰2查临时 LOB 生命周期用完是否释放连接池长会话是否越积越多是否不必要的NOCACHE3再评估VM_BUFFER_SIZE确认 SQL/调度/LOB 合理后再改多为 SPFILE 重启类变更先点名再动刀4再评估 SWAP 扩容只缓解容量与 IO 顶死不能替代SQL/LOB 治理也常见这些坑一见换出就扩容把 SWAP 高当成内存泄漏只看全局不看会话采一次样就断定 LOB 泄漏没有LOB_DATA仍硬扣 LOB没跟业务确认就杀会话或改参数。视图当然可以手查更省事的是ytop -f swap.sql→ytop -f sql.sql4. 先跑 swap.sqlSWAP 告警或变慢时一条命令往往就够ytop-fswap.sql输出里按段看段看什么异常时常见样子1 参数VM_BUFFER_SIZE等buffer 是否过小2GV$VMFREE/SWOUT/FSWAPFREE≈0且SWOUT上升3 水位SWAP / TEMP 的 USED_PCTSWAP 持续上涨4 段LOB会话TSSWAP的MB、SEGTYPE、nc、sql_id谁在占 SWAP5 VM 会话cswo/swo/ event谁在猛换页未必已有大段抄到 sql_id 后再ytop-fsql.sql远端可用ytop -t host -f swap.sql或在库机直接跑。5. 案例一临时 LOB 顶高 SWAP先看全局页和水位ytop-fswap.sqlI TOTAL FREE OPENED CLOSED SWOUT CTRL FSWAP -- ---------- ---------- ---------- ---------- ---------- ---------- ---------- 1 21196 235 444 20515 6722 2 0 TABLESPACE_NAME SIZE_MB FREE_MB USED_MB USED_PCT ---------------- ---------- ---------- ---------- -------- SWAP 2432 2011 421 17.3 TEMP 64 59 5 7.8SWOUT6722SWAP 已用约 421MB17.3%。FREE还剩一点说明 buffer 紧而且已经往 SWAP 换了。再看谁在换页ytop-fswap.sqlSID_TID EVENT USERNAME SQL_ID EXECT PROGRAM COPN CSWO SWO SWI ALC IOW EXT ------------------ ---------------------- ---------- --------------- ------ -------------- ------ ------ -------- -------- -------- -------- ------ 1.44.30.880659 SYS .dbnkcw6u8j20u 1.17M /data/yashan/y 0 2.7K 4K 0 35.8K 0 4K 1.46.25.880661 SYS .dbnkcw6u8j20u 1.17M /data/yashan/y 0 4K 1.5K 0 27.4K 0 1.5K同一条dbnkcw6u8j20uCSWO在几千。SQL_ID列有时带SEL.前缀还会截断抄工单时用完整 sql_id。临时段也对得上ytop-fswap.sqlUSERNAME SID_TID SQL_ID TS SEGTYPE MB EXTENT CA NC AB EVENT ------------ ---------------- --------------- -------- ---------- ------- ------ ---- ----- ---- ------------------ SYS 1.46.25 dbnkcw6u8j20u SWAP LOB_DATA 31.69 3985 0 800 0 SYS 1.44.30 dbnkcw6u8j20u SWAP LOB_DATA 21.78 2737 0 800 0SID 44/46SWAP 上LOB_DATA大约 2232MB同行列nc800NOCACHE且不掉。文本侧是循环DBMS_LOB.CREATETEMPORARY(..., FALSE)nocache对临时 LOB 反复WRITEAPPEND还长期持着。caCACHE多压vm_buffernc更容易落到 SWAP 的LOB_DATA。这条线干净LOB →LOB_DATASWAP → 高nc→ 高CSWO。6. 案例二HASH JOIN 打穿 vm_bufferSEGTYPE 却是 Unknown手册里SEGTYPE有HASH这一项实际踩坑时有两点要注意vm_buffer还宽裕时会话侧可能已经有换出计数临时段却长时间没有行——别因此放过。buffer 打穿、SWAP 水位上来以后段会出现但类型未必显示成HASH。把 buffer 收紧、HASH 工作集做大以后ytop-fswap.sqlI TOTAL FREE OPENED CLOSED SWOUT CTRL FSWAP -- ---------- ---------- ---------- ---------- ---------- ---------- ---------- 1 2046 0 1050 986 5357 9 14788 TABLESPACE_NAME SIZE_MB FREE_MB USED_MB USED_PCT ---------------- ---------- ---------- ---------- -------- SWAP 2432 1172 1260 51.8 TEMP 64 59 5 7.8FREE0SWOUT5357SWAP 用到约 1260MB51.8%。FSWAP14788。会话上的 event 已经写明白了ytop-fswap.sqlSID_TID EVENT USERNAME SQL_ID EXECT PROGRAM COPN CSWO SWO SWI ALC IOW EXT ------------------ ---------------------- ---------- --------------- ------ -------------- ------ ------ -------- -------- -------- -------- ------ 1.38.1266.896498 swapping out vm block SYS SEL.3n81f1dnhkh 9.46S /data/yashan/y 1.1K 5.4K 305.7K 300.4K 8.7K 50 6.7KSWO/SWI到了 30 万级IOW50。sql_id 完整是3n81f1dnhkhkv。临时段有行但类型是Unknownytop-fswap.sqlUSERNAME SID_TID SQL_ID TS SEGTYPE MB EVENT PROGRAM ------------ ---------------- --------------- ---------- ------------ -------- -------------------- -------------- SYS 1.38.1266 3n81f1dnhkhkv SWAP Unknown 41.86 swapping in vm block /data/yashan/y再看文本和计划ytop-fsql.sql# sql_id 3n81f1dnhkhkv文本样例SELECT/* USE_HASH(a b) FULL(a) FULL(b) */COUNT(*)FROM...a,...bWHEREa.c2b.c2ANDa.idb.id计划样例Plan Hash Value: 3673659905 |Id|Operation |Name | |--|--------------------------|------------| | 0|SELECT STATEMENT | | | 1| AGGREGATE | | | 2| HASH JOIN INNER | | | 3| TABLE ACCESS FULL |... (A) | | 4| HASH GROUP | | | 5| TABLE ACCESS FULL |... (B) |合在一起看UnknownSWAP、swapping * vm block、计划又是 HASH JOIN就按 HASH 换出处理别因为SEGTYPE不是HASH就停。Unknown同样要当换出段看。SWOUT0也不等于没事会话侧分配/打开计数可能已经很高只是还没换出去。7. 两条线对照项LOBHASH打穿后sql_iddbnkcw6u8j20u3n81f1dnhkhkv段类型LOB_DATASWAPUnknownSWAP会话换出高CSWOeventswapping out vm blockSWO/SWI 很高文本/计划nocache 临时 LOBHASH JOIN 双侧全表全局SWOUT6722SWAP≈421MBFREE0SWOUT5357SWAP≈1260MB若要看历史等待或 TOP SQL可以再叠 ASH 相关脚本前提是库上 ASH 开着。8. 建议告警先跑swap.sql把参数、FREE/SWOUT、水位、段和会话一次看完。盯swapping * vm block以及CSWO/SWO/IOW/ALC抄完整 sql_id。见到LOB_DATA按临时 LOB 查见到UnknownSWAP 结合计划判断是不是 HASH/中间结果换出。段暂时没有行也不要放过会话侧的换出计数。拿到 sql_id 后跑sql.sql先定性 HASH / SORT / LOB再谈改写、限流或扩容。库内 SWAP 和操作系统 swap 不是一回事需要时用sar/iostat对照磁盘。连续采两三次看SWOUT、LOB 和临时段有没有回落。定位清楚再动VM_BUFFER_SIZE或扩 SWAP。内存参数往往要改配置并重启才能缩小先改参数容易把根因盖住。9. 总结SWAP 异常时不必从零拼动态性能视图。常用路径ytop -f swap.sql→ 抄 sql_id →ytop -f sql.sql。临时 LOB 一侧多见LOB_DATASWAP再加高nc、高CSWO。HASH 一侧buffer 打穿后换出很猛段类型却可能是Unknown要靠计划和swapping * vm block认。先点名再优化。
返回列表