SET SERVEROUTPUT ON SIZE UNLIMITED;
DECLARE
-- 自定义参数:采样间隔(秒)、采样次数
p_sample_interval INTEGER := 300; -- 5分钟,可修改为60(1分钟)、1800(30分钟)等
p_sample_times INTEGER := 10; -- 采样10次,可根据需要调整
-- 变量定义
v_prev_writes NUMBER; -- 上一次的总写入字节数
v_curr_writes NUMBER; -- 当前的总写入字节数
v_delta_bytes NUMBER; -- 时间窗口内的写入增量(字节)
v_delta_mb NUMBER; -- 时间窗口内的写入增量(MB)
v_rate_mb_per_min NUMBER; -- 写入速率(MB/分钟)
v_sample_start TIMESTAMP; -- 采样开始时间
v_sample_end TIMESTAMP; -- 采样结束时间
-- 获取所有回滚段的总写入量
CURSOR c_total_writes IS
SELECT SUM(writes) AS total_writes FROM v$rollstat;
BEGIN
-- 初始化:获取第一次的总写入量
OPEN c_total_writes;
FETCH c_total_writes INTO v_prev_writes;
CLOSE c_total_writes;
DBMS_OUTPUT.PUT_LINE('=============================================');
DBMS_OUTPUT.PUT_LINE('Undo 写入速率趋势统计(MB/分钟)');
DBMS_OUTPUT.PUT_LINE('采样间隔:' || p_sample_interval || '秒 | 采样次数:' || p_sample_times);
DBMS_OUTPUT.PUT_LINE('=============================================');
DBMS_OUTPUT.PUT_LINE(RPAD('采样时间', 25) || RPAD('总写入量(MB)', 15) || RPAD('增量(MB)', 12) || '速率(MB/分钟)');
DBMS_OUTPUT.PUT_LINE('----------------------------------------------------------------------');
-- 循环采样
FOR i IN 1..p_sample_times LOOP
-- 记录采样开始时间
v_sample_start := SYSTIMESTAMP;
-- 等待指定的采样间隔
DBMS_LOCK.SLEEP(p_sample_interval);
-- 获取当前总写入量
OPEN c_total_writes;
FETCH c_total_writes INTO v_curr_writes;
CLOSE c_total_writes;
-- 计算增量和速率
v_delta_bytes := v_curr_writes - v_prev_writes;
v_delta_mb := ROUND(v_delta_bytes / 1024 / 1024, 3); -- 转换为MB,保留3位小数
-- 速率 = 增量MB / (采样间隔(秒)/60)
v_rate_mb_per_min := ROUND(v_delta_mb / (p_sample_interval / 60), 3);
-- 记录采样结束时间(输出用)
v_sample_end := SYSTIMESTAMP;
-- 输出当前采样结果
DBMS_OUTPUT.PUT_LINE(
RPAD(TO_CHAR(v_sample_end, 'YYYY-MM-DD HH24:MI:SS'), 25) ||
RPAD(ROUND(v_curr_writes / 1024 / 1024, 3), 15) ||
RPAD(v_delta_mb, 12) ||
v_rate_mb_per_min
);
-- 更新上一次的写入量,用于下一次计算
v_prev_writes := v_curr_writes;
END LOOP;
DBMS_OUTPUT.PUT_LINE('----------------------------------------------------------------------');
DBMS_OUTPUT.PUT_LINE('统计完成!');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('脚本执行出错:' || SQLERRM);
RAISE;
END;
/
=============================================
Undo 写入速率趋势统计(MB/分钟)
采样间隔:300秒 | 采样次数:10
=============================================
采样时间 总写入量(MB) 增量(MB) 速率(MB/分钟)
----------------------------------------------------------------------
2026-03-03 13:10:07 45952.287 -6664.657 -1332.931
2026-03-03 13:15:07 42893.938 -3058.349 -611.67
2026-03-03 13:20:07 43371.029 477.091 95.418
2026-03-03 13:25:07 44181.004 809.975 161.995
2026-03-03 13:30:07 45269.015 1088.01 217.602
2026-03-03 13:35:07 46770.485 1501.47 300.294
2026-03-03 13:40:07 49512.263 2741.778 548.356
2026-03-03 13:45:07 47833.671 -1678.591 -335.718
2026-03-03 13:50:07 48990.828 1157.157 231.431
2026-03-03 13:55:07 49354.229 363.401 72.68
----------------------------------------------------------------------
统计完成!
PL/SQL procedure successfully completed.