前一期看了Oracle在redo上保持事务前滚的一致性,同样Oracle在Undo的管理机制也是现代事务型数据库的工程典范。核心在于通过多版本并发控制(MVCC)技术,在保障数据一致性与提升系统性能之间实现精妙平衡。Undo机制构建了原子事务的物理基础,通过存储数据前像实现秒级回滚。MVCC架构使读写操作完全解耦。Undo的智能空间管理(AUM)和保留期自动优化特性,精准控制RTO/RPO指标。通过UNDO_RETENTION GUARANTEE策略,可以为业务侧带来数据保险的时间窗口。引出另外另外一个话题:Flashback的实现对Undo有要求,然而两者处理的事务又大大不同(单开一期),这次重点是Oracle的Undo机制。
一、Undo机制核心功能与技术原理
1. 核心功能矩阵
|--------|-----------------------|--------------------------------------|
| 功能类别 | 具体实现 | 技术原理 |
| 事务回滚 | 回滚单条SQL或整个事务 | 存储数据前镜像链表,通过回滚指针(ROLL_PTR)构建版本链 |
| 读一致性 | MVCC多版本控制 | 基于SCN(System Change Number)构建一致性快照视图 |
| 实例恢复 | 崩溃后回滚未提交事务 | SMON进程应用Undo日志回滚未提交事务 |
| 闪回技术 | Flashback Query/Table | 时间戳与SCN映射,访问历史Undo数据 |
| 临时表优化 | 12c+临时Undo | 隔离存储临时表变更,减少Redo生成 |
2. 技术演进历程
Oracle 7-8i:手动回滚段
- 需要DBA手动创建和管理回滚段
- 易出现空间争用错误(ORA-01555)
- 事务回滚需扫描整个段,效率低
Oracle 9i:自动Undo管理(AUM) - 引入UNDO_TABLESPACE参数
- 自动分配和管理Undo段
- UNDO_RETENTION参数控制保留时间
Oracle 10g:IMU内存优化 - In-Memory Undo(IMU)技术
- 共享池中分配私有Undo缓冲区
- 减少60%磁盘I/O和Redo生成
Oracle 11g:自动保留期调整 - 动态计算TUNED_UNDORETENTION
- 自动避免ORA-30036(空间不足)和ORA-01555(快照过旧)
Oracle 12c:临时Undo - 全局临时表(GTT)的Undo存入临时表空间
- 减少75% Redo日志量
- 物理备库支持临时表DML操作
Oracle 19c~23ai:混合列压缩 - Undo数据列式存储压缩
- 减少40%空间占用
- 优化数据仓库场景
二、Undo日志技术原理深度解析
Undo日志是内容,Undo表空间是容器。
所有事务生成的Undo日志最终持久化到Undo表空间文件中。
1. 数据结构
Undo记录头结构:
- XID:事务ID(16字节,包含回滚段号+槽号+序列号)
- UBA:前序Undo记录地址(文件号+块号+记录偏移)
- Opcode:操作类型标识(0x02=INSERT, 0x04=UPDATE, 0x10=DELETE)
- Flags:状态标志位(活动/过期等)
- Data Length:数据长度
数据区结构: - RowID:修改行的物理地址
- ColID:修改列标识符
- OldVal:修改前的列值
2. 存储架构
层级结构:
- Undo表空间:专用存储容器
- 数据文件:物理存储文件(如undotbs01.dbf)
- 回滚段:每个事务绑定独立段
- 区(Extents):8个连续块组成的分配单元
- 块(Blocks):标准8KB Oracle块
- Undo记录:实际存储单元
空间状态管理:
- 活动区(Active):事务进行中,强制保留
- 未过期区(Unexpired):已提交+保留期内,优先保留
- 过期区(Expired):超保留期,可覆盖使用
3. 写入流程
- DML操作触发Undo记录生成
- Undo记录写入Buffer Cache
- 同步生成Redo日志(Write-Ahead Logging)
- LGWR进程将Redo写入日志文件
- DBWn进程异步将Undo数据写入磁盘
- 事务提交时更新状态
三、关键配置与管理策略
1. 核心参数配置
bash
-- 基础配置 --
ALTER SYSTEM SET undo_management = AUTO; -- 启用自动管理
ALTER SYSTEM SET undo_tablespace = undotbs2; -- 指定表空间
ALTER SYSTEM SET undo_retention = 1800 SCOPE=BOTH;-- 保留30分钟
--
show parameter undo;
NAME TYPE VALUE
----------------- ------- --------
temp_undo_enabled boolean FALSE
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
-- 高级优化 --
ALTER SYSTEM SET "_in_memory_undo" = TRUE; -- 启用IMU(10g+)
ALTER SYSTEM SET temp_undo_enabled = TRUE; -- 启用临时Undo(12c+)
--System altered.
2. 表空间管理
创建表空间:
bash
CREATE UNDO TABLESPACE undotbs2
DATAFILE '/opt/oracle/oradata/FREE/FREEPDB1/undotbs2_01.dbf' SIZE 20G
AUTOEXTEND ON NEXT 1G MAXSIZE UNLIMITED
RETENTION GUARANTEE; -- 关键系统启用保证模式
空间维护操作:
bash
-- 空间回收
ALTER TABLESPACE undotbs1 SHRINK SPACE KEEP 15G;
-- 表空间切换
ALTER SYSTEM SET UNDO_TABLESPACE = undotbs2;
-- 删除旧表空间
DROP TABLESPACE undotbs1 INCLUDING CONTENTS AND DATAFILES;
3. 监测体系
空间压力监控:
bash
SELECT
TO_CHAR(begin_time, 'YYYY-MM-DD HH24:MI') AS snapshot_time,
undoblks AS undo_blocks_generated,
maxquerylen AS longest_query_sec,
ssolderrcnt AS ora_01555_count,
tuned_undoretention AS actual_retention_sec
FROM v$undostat
ORDER BY begin_time DESC;
事务级监控:
bash
SELECT
s.sid,
s.username,
t.start_time,
t.used_ublk AS undo_blocks_used,
t.used_urec AS undo_records_used
FROM v$transaction t
JOIN v$session s ON t.ses_addr = s.saddr;
--11g 生产库
SID USERNAME START_TIME UNDO_BLOCKS_USED UNDO_RECORDS_USED
-- -------------------- -------------------- ---------------- ------------
3401 HIS50 01/15/24 21:20:00 1 1
文件级监控:
bash
SELECT
file_name,
bytes/1024/1024 AS size_mb,
maxbytes/1024/1024 AS max_size_mb,
autoextensible,
increment_by * 8192/1024/1024 AS increment_mb
FROM dba_data_files
WHERE tablespace_name = 'UNDOTBS1';
---
FILE_NAME SIZE_MB MAX_SIZE_MB AUTOEXTENSIBLE INCREMENT_MB
__________________________________________________ __________ ___________________ _________________ _______________
/opt/oracle/oradata/FREE/FREEPDB1/undotbs01.dbf 345 33554431.9765625 YES 5
四、验证脚本集
1. 读一致性验证
bash
--会话1
UPDATE HR.employees SET salary = 15000 WHERE employee_id = 100;
-- 不提交事务
--会话2
SELECT salary FROM HR.employees e WHERE e.employee_id = 100;
-- 应返回修改前的值(比如6000)
2. 保留期保证验证
bash
-- 设置保留保证
ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;
-- 生成测试数据并等待超保留期
BEGIN
UPDATE HR.employees SET salary = salary * 1.1;
COMMIT;
DBMS_LOCK.SLEEP(2000); -- 等待超过undo_retention
END;
/
-- 尝试历史查询
SELECT salary FROM HR.employees
AS OF TIMESTAMP SYSTIMESTAMP - INTERVAL '30' MINUTE
WHERE employee_id = 100;
-- 应成功返回历史数据
3. 临时Undo性能验证
bash
-- 启用临时Undo
ALTER SESSION SET temp_undo_enabled = TRUE;
-- 创建临时表
CREATE GLOBAL TEMPORARY TABLE temp_emp AS SELECT * FROM HR.employees;
-- 测试I/O对比
SET AUTOTRACE STATISTICS;
-- 临时表操作
INSERT INTO temp_emp SELECT * FROM HR.employees;
COMMIT;
-- 记录统计信息中的redo size
-- 常规表操作
INSERT INTO HR.employees SELECT * FROM employees WHERE 1=0;
ROLLBACK;
-- 比较redo size差异(临时表应显著减少)
4. IMU效果验证
bash
-- 检查IMU状态
SELECT name, value
FROM v$sysstat
WHERE name LIKE '%IMU%flush%';
--
NAME VALUE
--------------------------------------------- ----------
IMU recursive-transaction flush 3401
IMU undo retention flush 0
IMU ktichg flush 2
IMU bind flushes 0
IMU mbu flush 0
-- 生成负载测试
DECLARE
CURSOR c_emp IS SELECT * FROM HR.employees FOR UPDATE;
BEGIN
FOR r IN c_emp LOOP
UPDATE HR.employees SET salary = salary * 1.01 WHERE CURRENT OF c_emp;
END LOOP;
COMMIT;
END;
/
-- 再次检查IMU统计
五、最佳实践指南
1. 容量规划公式
bash
所需空间(GB) = (DPM × ARS × UR) / (1024³) × 1.5
- DPM:每分钟DML操作数
- ARS:平均行大小(字节)
- UR:保留期(分钟)
- 1.5:安全系数(含元数据开销)
2. 高可用架构设计
多表空间轮换策略
- 创建至少两个Undo表空间
- 定期切换:ALTER SYSTEM SET UNDO_TABLESPACE=undotbs2;
- 保留旧表空间24小时后删除
空间保障策略
bash
-- 关键系统启用保留保证
ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;
3. 参数优化对比
|----------|-----------------|-------|----------|------|
| 场景类型 | undo_retention | IMU | 临时Undo | 压缩 |
| OLTP系统 | 2小时 | 启用 | 启用 | 禁用 |
| 数据仓库 | 6小时 | 按需 | 按需 | 启用 |
| 金融系统 | 12小时+保证 | 启用 | 启用 | 禁用 |
| 开发环境 | 24小时 | 可选 | 可选 | 可选 |
4. 故障处理一览
|-----------|----------|-----------------------|
| 故障现象 | 可能原因 | 解决方案 |
| ORA-01555 | Undo保留不足 | 增加UNDO_RETENTION或表空间 |
| ORA-30036 | 空间不足 | 扩展表空间或启用AUTOEXTEND |
| 闪回失败 | 历史数据不可用 | 启用RETENTION GUARANTEE |
| 性能下降 | IMU未启用 | 检查"_in_memory_undo"参数 |
六、演进趋势与未来方向
多租户、云原生优化
- CDB/PDB多租户Undo隔离
- 基于负载的自动伸缩策略
- 跨区域Undo复制
- AI的到来自动预测和优化
持久内存应用 - 利用PMEM存储Undo日志
- 持久内存直接访问加速
- 崩溃恢复时间缩短90%
性能数据 :
Oracle 19c在混合负载下,IMU+临时Undo组合可降低整体I/O 45%,提升事务吞吐量30%(from:Oracle官方实验室基准测试)。
七、使用体验
Oracle Undo机制通过多阶段技术演进,已从基础的事务回滚工具发展为支持多版本控制、闪回操作和多租户、云原生优化的综合数据管理平台。关键最佳实践包括:
- 根据业务负载科学规划空间容量
- OLTP系统启用IMU和临时Undo
- 关键业务启用RETENTION GUARANTEE
- 建立多层次监控预警体系
- 定期进行健康检查和性能优化