简介:一份面向DB2数据库运维人员的性能故障案例文档,聚焦系统临时表空间(TEMPSPACE1)异常膨胀导致SQL执行时间显著变长的问题。资源基于某银行生产环境的真实排障经历,完整记录了从发现ACTIVE SESSION数量激增、常规检查无果,到最终定位临时表空间达10GB为根因的过程。文档重点介绍了DB2性能分析方法论,包括db2top监控活跃会话、LATCH等待分析、堆栈收集与db2trc工具暂停实例等技巧,并给出优化SQL、调整临时表空间参数、清理临时对象等解决措施,对处理类似数据库性能瓶颈有直接参考价值。资源为单个doc文档,大小607KB,内容结构清晰,已有5898人学习下载,适合有一定DB2基础的DBA或性能调优工程师阅读。
1. 系统临时表空间过大:为什么性能问题总在这时候集体爆发
某个周二的晚上十一点,批量作业刚跑起来,监控大屏上系统临时表空间的使用率从 20% 一路冲到 97%,紧接着应用连接排队,核心查询的排序时间翻了不止三倍。这类故障一旦出现,应用方第一反应是加机器、加连接,DBA 第一反应是查 temp 表空间——但真正的原因往往不是表空间容量不够,而是某个 SQL 在排序或哈希连接阶段把临时空间吃满了。
DB2 系统临时表空间(System Temporary Table Space)是排序、分组、哈希连接、索引创建和 REORG 的默认落盘位置。它一旦被撑大,影响的不只是自身容量,还会拖慢所有依赖排序的查询,甚至触发锁等待和应用超时。这篇笔记按“谁吃掉了临时表空间 → 怎么定位 → 怎么处理 → 日常怎么防”这条线展开,给出我在生产环境里反复验证过的命令、参数和避坑经验。适合正在处理同类问题的 DBA,也适合被临时表空间告警缠身的应用开发。
2. 临时表空间被谁撑大的:排序、HASH JOIN 与隐式转换的连锁反应
2.1 系统临时表空间和用户临时表空间:监控前先分清两类对象
很多同事一看到“临时表空间”就去查USERSPACE1,这是最常见的方向搞错。DB2 数据库里的临时表空间分两类,用途完全不同。
系统临时表空间(System Temporary Table Space):DB2 内部使用,排序、哈希连接、索引创建、REORG、物化查询表刷新都要靠它暂存中间结果。它在数据库创建时默认生成,名字通常是TEMPSPACE1。这类表空间不能被用户直接建表。
用户临时表空间(User Temporary Table Space):专门给DECLARE GLOBAL TEMPORARY TABLE这种会话级临时表使用,没有它,应用层临时表就建不出来。
排查性能问题时,90% 的流量都集中在系统临时表空间上。确认类型用一条命令就行:
db2 list tablespaces for sample show detail输出里每一段开头会有Tablespace ID、Type和Contents,重点看Contents:
Tablespace ID = 3 Type = System managed space Contents = System Temporary data State = 0x0000Contents显示System Temporary data才是系统临时表空间。如果看到的是User Temporary data,那是另一条排查路径。分清这一点,告警来了才不会看错对象。
2.2 消耗临时空间的四大来源:SORT、HASH JOIN、索引创建与 REORG
系统临时表空间的消耗来源不是随机的,基本就这四类,按出现频率排序:
排序操作。ORDER BY、GROUP BY、DISTINCT、集合运算UNION和MINUS、OLAP开窗函数,只要排序内存不够,中间结果就写到系统临时表空间。这是最常见的一类。
哈希连接。DB2 在HASH JOIN构建阶段,会把小表在内存里建哈希表,如果内存阈值不够或者统计信息严重失真,哈希表会被迫下探到临时表空间。典型场景是两个大表做等值连接但优化器错误评估了行数。
索引创建与 REORG。CREATE INDEX排序索引键值,REORG TABLE需要临时段来重组数据页,REORG INDEXES也一样。这类操作平时不显眼,一旦在白天窗口执行,临时表空间使用率会瞬间抬升。
声明全局临时表本身也会占空间,但注意它用的是用户临时表空间,如果业务代码里大量使用 DGTT 且没有及时DROP TABLE,同样会给你“临时表空间又满了”的错觉。
2.3 SHEAPTHRES、SHEAPTHRES_SHR 和 SORTHEAP:三个参数如何控制排序落盘
先要纠正一个常见误区:临时表空间使用率高,不代表表空间本身是瓶颈。排序是先走内存,内存不够才落盘,落盘的位置才是系统临时表空间。所以排查时必须把三个参数放在一起看。
SORTHEAP:数据库级参数,代表单次排序可用的私有内存上限,默认值在 256 到 4096 页之间,单位是 4KB 页。可以动态调整。
SHEAPTHRES_SHR:数据库级参数,限制所有共享排序活动在缓冲池里占用的总量。注意它限制的是“共享排序内存”,不限制私有排序。DB2 会自动管理的话,显示为 0。
SHEAPTHRES:实例级参数,控制私有排序的内存总量上限。老版本里它经常被设成固定值,设置不当会导致大量排序直接落盘,表现为“还没到高峰,临时表空间先满了”。
它们之间的关系,我用一句话概括:一个排序申请SORTHEAP大小,但所有排序加在一起不能超过SHEAPTHRES或SHEAPTHRES_SHR的限制,超出的部分全部写进系统临时表空间。
生产库里最常见的翻车组合是:SORTHEAP调得很大,但SHEAPTHRES保持很小,结果大量排序并发时仍然疯狂落盘,临时表空间被瞬时打爆。这种情况调SORTHEAP是没用的,真正的调节对象是SHEAPTHRES。
查看当前值的方法:
db2 get db cfg for sample | grep -i "SORTHEAP" db2 get db cfg for sample | grep -i "SHEAPTHRES_SHR" db2 get db cfg for sample | grep -i "SHEAPTHRES"2.4 隐式转换如何把简单查询变成临时表空间大户
这一节值得应用开发重点看。很多临时表空间爆掉的 SQL,表面上看 SELECT 语句长得挺干净,问题出在谓词类型不匹配。
某个查询在 WHERE 里把字符串列和数字常量比较:
SELECT order_id, cust_name FROM order_tab WHERE order_no = 123456;如果order_no是VARCHAR类型,DB2 优化器为了比较,要么把列转成数字,要么把常量转成字符串。一旦选择了对列做转换,索引就废了。更麻烦的是,如果目标列上要逐个转换并排序,优化器就可能选择排序操作把结果暂存到系统临时表空间。
避免这种问题,常见做法是换个方向,把常量转成列的类型:
SELECT order_id, cust_name FROM order_tab WHERE order_no = CHAR(123456);还有一种情况是判断字符串字段是否由数字构成。比如代码里先查出一堆字符串,再在应用层判断是不是数字,或者在 SQL 里用正则过滤:
SELECT id, tag_value FROM temp_tag_tab WHERE tag_value REGEXP_LIKE(tag_value, '^[0-9]+$');这类写法本身不是不行,但会对大结果集产生额外开销。如果这个判断发生在 JOIN 和排序之前,临时表空间占用会成倍叠加。DB2 判断数字字符串更高效的做法是先压缩数据范围,再用TRANSLATE或CASE WHEN做一次轻量判断,尽量让过滤发生在扫描早期。
临时表空间被撑大的根因永远是“有操作需要中间结果落盘”,而不是“临时文件天生就大”。带着这个认知去看监控,方向不会偏。
3. 定位临时表空间真凶:db2pd 与 MON_GET_TABLESPACE 的排查命令链
3.1 先确认容量:LIST TABLESPACES SHOW DETAIL
告警触发后的第一步不是抓 SQL,是确认当前使用率是持续走高还是瞬时脉冲。用最直接的命令:
db2 connect to sample db2 list tablespaces show detail聚焦系统临时表空间那段输出,重点看两行:
Total pages = 1048576 Used pages = 990452Used pages 除以 Total pages 就是当前使用率。如果 Used pages 接近总量且数值还在跳动,说明正在有排序活动落盘;如果数值稳定在高位,可能是有长事务占用,也可能是表空间扩展后没有收缩回来的历史残留。
进一步看当前有哪些连接在活跃状态:
db2 list applications for database sample show detail记录下Application handle、Status和Statement text,后面用 db2pd 精确锁定。这一步别跳太快,很多 DBA 上来就查 SQL,忽略了一个事实:临时表空间高水位可能是十分钟前的那次批量作业造成,真正“正在跑”的 SQL 反而只占小头。
3.2 用 db2pd 抓正在跑的 SQL 与排序状态
LIST APPLICATIONS看的是连接级信息,粒度还不够。db2pd 能直接深入实例内存,不需要建立新连接,这在实例接近打满时非常有用。
先抓表空间瞬时状态:
db2pd -d sample -tablespaces输出里能看到各个表空间的TbspaceID、State、TotalPgs和UsablePgs。如果State不是0x0000而是别的值,比如有容器异常,优先处理容器问题,否则排序再正常也会被异常状态放大。
再抓谁在消耗临时表空间:
db2pd -d sample -applications关注AppHandl、Status、TranHolds这几列。很多吃临时空间的事务会长时间停留在Preparing或Executing状态,少数情况下能看到Sorting。这些连接对应的AgentID可以继续关联到动态 SQL 缓存:
db2pd -d sample -dynamic在dynamic输出里根据AppHandl对应的StmtUID找到具体语句,用num_orders或sort_hash_jos这类字段判断它是否做了大量排序。这一步抓到的 SQL 就是后续改写和优化的直接证据。
3.3 用 MON_GET_TABLESPACE 视图统计临时空间消耗趋势
db2pd 看到的是“当前此刻”,如果故障是几分钟前发生的,瞬时数据可能已经错过。要回看趋势,用监控视图最合适。
SELECT varchar(tbsp_name, 30) AS tbsp_name, tbsp_type AS tbsp_type, tbsp_total_size_kb AS total_kb, tbsp_used_size_kb AS used_kb, tbsp_utilization_percent AS used_pct FROM TABLE (MON_GET_TABLESPACE(NULL, -2)) AS T WHERE tbsp_type = 1MON_GET_TABLESPACE(NULL, -2)的第一参数表示不过滤表空间名,-2表示查所有数据库分区成员。返回结果里,tbsp_type为 1 的是系统临时表空间,其他类型可以根据需求过滤。
这个查询适合放进运维脚本里周期性落库,每隔 30 秒跑一次,把临时表空间的使用率写入监控表。故障复盘时按时间轴回放,能准确看到飙升起点,再把那个时段的 SQL 日志拉出来对比。
如果实例版本老,MON 视图不可用,退而求其次用快照:
db2 get snapshot for tablespaces on sample快照输出里的Snapshot timestamp和Buffer pool temporary data logical reads能辅助判断排序强度。相比 MON 视图,快照的粒度粗,但聊胜于无。
3.4 结合 db2top 和应用日志圈定窗口期
命令敲得再熟,也架不住信息分散。我一般会同步开一个 db2top:
db2top -d sample进入后先看 Tablespace 面板,确认临时表空间使用率;再切到 Sorts 面板看每秒排序次数和排序堆溢出的比例。这两个面板放在一起,能快速区分是“大量小排序挤在一起”还是“少数大排序吃满空间”。
前者的处理方向是削减并发或微调SHEAPTHRES_SHR,后者的处理方向是优化单条 SQL。二者方向完全不同,处理前必须分清楚。
如果 db2top 显示排序溢出比例持续超过 30%,同时临时表空间使用率同步增长,那基本可以断定排序内存不足。这时去应用的日志系统里拉同一时间段的慢 SQL 列表,按执行次数排序,找出窗口期内被反复执行的 TOP N。
至此,临时表空间问题已经从“表空间告警”还原成了“具体 SQL + 具体时间点”。接下来才是真正动手处理。
4. 系统临时表空间过大怎么办:参数调整、SQL 改写与 db2stop/start 时机
4.1 调整数据库参数:SORTHEAP 与 SHEAPTHRES_SHR 怎么配合
处理临时表空间过大,很多人都想着“把临时表空间扩容”,这是最直接的思路,但可能治标不治本。我一般先调三个排序参数,再决定要不要扩容量。
先看当前值,再按下面的顺序调整:
db2 update db cfg for sample using SORTHEAP 4096 db2 update db cfg for sample using SHEAPTHRES_SHR 64000参数说明:
SORTHEAP4096 表示单次排序最多使用 4096 个 4KB 页,也就是 16MB。这是给每个排序的起步内存。SHEAPTHRES_SHR64000 表示共享排序总量限制为 250MB 左右。这个值要结合并发量看,不是越大越好。SHEAPTHRES是实例级参数,修改后要重启实例才生效。应急处理时先别动它,避免为了救火引入新的停机窗口。
调整的依据是:临时表空间使用率还在涨,但排序本身没有严重溢出,说明并发排序太多,优先加SHEAPTHRES_SHR;如果单纯是某个大查询排序溢出,优先加SORTHEAP,同时观察SHEAPTHRES上限会不会变瓶瓶颈。
这两个参数改完不要求重启数据库,但deactivate和activate一下更保险:
db2 deactivate db sample db2 activate db sample如果实例里还有活跃连接,deactivate会失败。这是正常的,说明参数修改在下次完全停止激活时也会生效,并不影响之后的新连接。
4.2 改写 SQL:消除排序、哈希连接和隐式转换
参数是给系统兜底的,SQL 才是决定临时表空间高度的天花板。改动 SQL 前先看执行计划,确认排序算子从哪里来。
先抓执行计划:
db2 explain plan for SELECT order_no, item_cnt FROM orders ORDER BY order_no; db2exfmt -d sample -1 -o exfmt.out如果exfmt.out里有独立的SORT节点,且它的Rows接近全表行数,说明这不是必要排序,是索引缺失或谓词写法有问题。优先看是否能用索引消除排序:
CREATE INDEX idx_orders_no ON orders(order_no);让优化器用索引的有序扫描替代显式排序。注意:如果查询里带了ORDER BY和GROUP BY混合,索引覆盖不一定完整,执行计划里仍然可能出现SORT。
二次元现象是哈希连接被滥用。大表小表连接时,优化器会选小表做哈希构建端,如果统计信息偏差导致系统误以为小表很大,哈希表就会膨胀落盘。这时重新收集统计信息比改写 SQL 更有效:
db2 runstats on table orders with distribution and detailed indexes all如果 RUNSTATS 之后临时表空间消耗仍然高,再改写连接顺序,用/+/*#$*/之类的语法不是好选择,正确做法是让业务 SQL 里先过滤再连接。比如:
SELECT ... FROM orders o INNER JOIN order_items i ON o.order_id = i.order_id WHERE o.pay_status = 'PAID'如果pay_status上过滤条件能先执行,参与哈希连接的行数会大幅下降。
隐式转换同样值得复查。前面提到的字符串列与数字常量比较,在 SQL 里改写成一个显式类型转换,往往能让优化器重新选择索引路径。
4.3 重建或迁移系统临时表空间:容器调整的可行与不可行
如果临时表空间使用率长期维持 80% 以上,业务 SQL 又无法快速优化,那就需要给表空间扩容或者搬迁。
自动存储数据库上,最简单的是直接扩展:
db2 alter tablespace tempspace1 resize (all 10000)参数10000的单位是 4KB 页,表示把所有容器统一扩展到 10000 页。自动存储管理的容器文件会随之增大。这个操作在线执行,不中断业务。
如果容器文件分布在不合理的磁盘上,或者旧表空间文件已经碎片化严重,可以重建一个系统临时表空间并切换过去:
db2 create temporary tablespace TMP_NEW pagesize 32 k managed by automatic storage; db2 alter database sample set default temporary tablespace TMP_NEW;注意顺序:必须先建新表空间并设为默认,等待旧连接全部结束,再删除旧表空间。
db2 drop tablespace tempspace1;删除前务必确认没有应用还在使用tempspace1。如果开发框架在连接池里缓存了指向旧临时表空间的语句,删除会直接引发连接报错。我在生产环境见过SQLCODE -147,就是因为旧连接没断开就去 drop。建议 drop 之前先切维护窗口,或者等一个业务低峰。
4.4 什么时候必须 db2stop/db2start:重启实例的代价与收益
临时表空间问题能不能靠重启实例解决,这是一个被反复问起的问题。回答分两层:
重启确实能清理残留在系统临时表空间上的临时段和未释放的排序上下文。特别是由于大量排序异常中断、缓冲池状态混乱引发的“使用率居高不下但现场没有 SQL”的情况,重启几乎是唯一快速恢复手段。
但重启是最后手段,不是第一手段。一次db2stop意味着所有连接被断开、未提交事务要回滚、缓冲池要重训。在核心系统上,这个成本远高于临时表空间短暂的“稳定”。
确需重启时,按严谨顺序执行:
db2 force applications all db2 deactivate db sample db2stop db2start db2 activate db sample如果force applications all后仍有连接挂着,通常是应用连接池没有及时释放,需要到应用服务器上确认进程退出。否则db2stop会长时间停在waiting for applications to complete。
另外要说清,重启解决的是“残留”,解决不了“根因”。如果临时表空间是被不可控的大排序打爆的,重启完跑同一条 SQL,还是会再次打爆。把重启省下来的时间去定位 SQL,是这份工作最划算的投入。
5. 系统临时表空间踩坑实录:五个案例与排查路径
5.1 现象:临时表空间使用率 100%,但“没有 SQL 在跑”
某次告警显示系统临时表空间使用率 98%,应用基本停摆。LIST APPLICATIONS看不到大量活跃排序,MON_GET_TABLESPACE也显示使用率高位徘徊。
原因:一个长时间运行的REORG TABLE后台任务正在重建索引,它不占用应用连接列表中的显式 SQL,但持续使用系统临时表空间作为重组索引的工作区。还有一种可能是某个排序代理段卡在Interrupted状态,遗留在表空间内没有释放。
解决:先查后台任务列表,确认是否有REORG或RUNSTATS在凌晨批量中遗留。db2pd -d sample -reorgs能看到表级重组状态。如果确实有任务在跑,让其自然完成,不要再叠加新作业;如果是中断遗留的代理段,则等待事务超时或安排维护窗口重启。
5.2 现象:盲目调大 SORTHEAP 后临时表空间反而更满
同事在临时表空间告警后把SORTHEAP从 1024 调到 8192,结果第二天使用率更高了,应用查询普遍变慢。
原因:SORTHEAP只控制单个排序的内存上限,改大后单个排序能吃更多的内存,但所有排序共享的实例级SHEAPTHRES没有同步提升。大量的排序并发在内存里互相“抢地盘”,竞争不过的排序还是会落盘,而且排序本身占用更久,临时表空间被占用更长时间。
解决:调整SORTHEAP时必须同步评估SHEAPTHRES_SHR和SHEAPTHRES。以单次排序 16MB、并发 200 个排序估算,共享阈值要留出 3.2GB 以上的空间。这不是越界调参能解决的,需要按实际并发量算。
5.3 现象:加了索引,SQL 还是走排序
某个ORDER BY查询,在排序列上建了索引,EXPLAIN一看,仍然有SORT节点,临时表空间照样被吃满。
原因:常见有两类。一类是统计信息过期,优化器不知道新索引存在,或者索引列分布信息失真导致索引成本被高估;另一类是谓词条件里对索引列做了函数运算,比如:
WHERE UPPER(cust_name) = UPPER('zhangsan')函数让索引失效,排序自然无法避免。
解决:先RUNSTATS重新收集统计信息;如果仍然走排序,检查 WHERE 条件是否在索引列上套了函数,改写为直接等值或范围比较。还解决不了,把EXPLAIN输出里的SORT节点完整截图,看排序发生在表扫描阶段还是连接阶段,针对具体阶段做分区裁剪或者物化查询表优化。
5.4 现象:db2stop 正常,db2start 却失败
为了清理临时表空间,执行了db2stop和db2start,结果数据库实例起不来了,报容器相关的错误。
原因:重启前有人为了“释放磁盘空间”,删除了临时表空间的容器文件,或者把目录结构做了迁移。DB2 启动时要重新打开所有容器,发现文件缺失直接中止启动。这属于典型的临时表空间清理误操作。
解决:不要手工删除表空间容器文件。系统临时表空间在空闲时也不会自动缩回容器文件大小,这是 DB2 的设计,不是故障。如果磁盘确实吃紧,用db2 alter tablespace调整容器大小,或者重建新临时表空间并切换默认指向,之后在旧表空间离线状态下再删除容器文件。容器文件的操作永远走 DB2 命令,不走操作系统的rm。
5.5 现象:临时表空间“用完不释放”,使用率居高不下
更有意思的是,查询已经结束、会话已经断开,系统临时表空间使用率仍然停在 70%。
原因:DB2 的系统临时表空间对空间的管理是“占有并复用”。排序或哈希连接完成后,空间会归还给表空间内部管理,但不一定归还给操作系统。自动存储的表空间按需扩展,扩展后不会自动收缩。所以从文件系统层面看,临时文件一直很大;从 DB2 内部看,内存页是可复用的。
解决:这不一定是故障,需要结合MON_GET_TABLESPACE的tbsp_used_size_kb判断。如果内部使用率仍然高,查连接池是否还握着空闲连接,某些框架的会话在断开后没有真正提交回滚,排序段残留。如果只是文件大、内部空闲,可以暂时不管,旺季调整db2 alter tablespace容量即可。
6. 把临时表空间纳入日常监控:脚本、阈值与 EXPLAIN 验证
6.1 监控脚本:采样 db2pd 输出到时间序列文件
我习惯在每台 DB2 服务器上放一段采样脚本,定时把系统临时表空间使用率写进 CSV,故障复盘时能直接拉出时间轴:
#!/bin/bash # 监控系统临时表空间使用率,每 60 秒采样一次 DB=sample OUT=/var/log/db2/tbsp_$(date +%Y%m%d).csv while true; do TS=$(date +%Y-%m-%d_%H:%M:%S) db2 connect to $DB >/dev/null 2>&1 db2 -x " SELECT varchar(tbsp_name,20)||','|| tbsp_used_size_kb||','|| tbsp_total_size_kb||','|| tbsp_utilization_percent FROM TABLE(MON_GET_TABLESPACE(NULL,-2)) AS T WHERE tbsp_type = 1 " | while read LINE; do echo "$TS,$LINE" >> $OUT done db2 terminate >/dev/null 2>&1 sleep 60 done脚本每秒依赖一个短连接,对实例有少量开销。在核心生产库上,建议二次开发成守护进程,用db2pd替代db2 connect,避免监控本身成为连接压力来源。CSV 文件按天切分,配合 Grafana 或任何时序平台导入后,就能直观看到临时表空间使用率的上升斜率。
6.2 阈值怎么设:使用率、持续时间和趋势的组合
不要只盯着“使用率 90% 告警”这一条规则。临时表空间的特点是,只要 SQL 排序结束,使用率会瞬间回落,单一的百分比阈值只会制造大量无用告警。
我一般设三档:
| 档位 | 触发条件 | 动作 |
|---|---|---|
| 关注 | 使用率 > 60%,持续 10 分钟 | 记录当前活跃 SQL,观察趋势 |
| 告警 | 使用率 > 80%,持续 10 分钟 | 立即执行 db2pd 抓应用,通知应用负责人 |
| 紧急 | 使用率 > 95%,持续 5 分钟 | 准备扩容或切换临时表空间,评估是否中断批量 |
趋势比绝对值重要。如果使用率从 20% 升到 60% 只用了 3 分钟,即使还没到 80% 的告警线,也要提前介入,因为它的斜率说明背后有大量排序正在落盘。阈值要与排序溢出率联动判断,单独看一方面是盲人摸象。
6.3 用 EXPLAIN 验证排序是否真正消除
处理完 SQL 后,验证环节不能省。用完整的执行计划校验排序是否还在:
db2 explain plan for SELECT order_no, sum(amount) FROM orders GROUP BY order_no WITH UR; db2exfmt -d sample -1 -o /tmp/exfmt.out打开exfmt.out,重点看两个地方:一是是否存在独立的SORT节点,二是SORT节点下面的Rows估算值。如果之前的问题 SQL 是ORDER BY order_no,现在计划里排序节点消失,说明索引已成功消除了排序;如果排序节点还在但Rows从全表行数降到了小范围,说明分区裁剪或谓词过滤起了作用。
还要对比改前改后的临时表空间使用率。改完 SQL 后,下一个批量窗口重新观察监控 CSV,确认峰值是否明显下降。只有当“执行计划无排序 + 监控峰值下降”两者同时满足,这次临时表空间优化才算真正闭环。
我做 DBA 这几年,系统临时表空间的问题处理了不少,慢慢养成了一个习惯:启动任何批量任务前,先花两分钟看一眼临时表空间基线和排序溢出率,而不是等告警响了再冲进机房。临时表空间不是不能涨,但每个 DBA 心里都得有一杆秤——它是在帮 SQL 完成工作,还是在帮烂 SQL 掩盖问题。前者可以接受,后者必须清理。希望这篇文章的做法能帮你在下一次告警来临时,少走一点弯路。
本文还有配套的精品资源,点击获取