Oracle Undo 深度解析
Oracle Undo 深度解析
适用版本:Oracle Database 10g / 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
Undo 是事务回滚与一致性读的基础[1]:
作用:
- 事务回滚
- 一致性读
- 闪回查询
- 实例恢复
详细见:Oracle Undo 表空间管理。
2. Undo 结构
2.1 表空间
CREATE UNDO TABLESPACE undotbs1
DATAFILE '/u01/oradata/undotbs01.dbf' SIZE 10G
AUTOEXTEND ON;
2.2 段
- 系统管理
- 自动扩展
- 自动收缩
2.3 区
- 自动分配
- 自动回收
3. Undo 记录
3.1 内容
- 修改前的数据
- 事务 ID
- SCN
- 操作类型
3.2 存储
- Undo Block
- Undo Segment
- Undo Tablespace
4. AUM(Automatic Undo Management)
4.1 启用
ALTER SYSTEM SET undo_management = AUTO;
ALTER SYSTEM SET undo_tablespace = undotbs1;
4.2 自动
- 自动分配段
- 自动扩展
- 自动收缩
- 自动调优
5. Undo Retention
5.1 设置
ALTER SYSTEM SET undo_retention = 3600;
-- 保留 1 小时
5.2 强制
ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;
-- 保证保留
ALTER TABLESPACE undotbs1 RETENTION NOGUARANTEE;
5.3 闪回
- Undo Retention 决定闪回能力
- 闪回查询/表/事务查询
详细见:Oracle 闪回技术。
6. 一致性读
6.1 流程
1. 查询开始记录 SCN
2. 读数据块
3. 如块 SCN > 查询 SCN
4. 从 Undo 重建前镜像
5. 返回一致数据
6.2 ORA-01555
- Undo 已被覆盖
- 增大 undo_retention
- 增大 Undo 表空间
7. 事务回滚
7.1 流程
1. ROLLBACK
2. 查找事务 Undo 记录
3. 应用前镜像
4. 释放锁
8. 实例恢复
8.1 流程
1. Redo 前滚(已提交 + 未提交)
2. 打开数据库
3. SMON 回滚未提交(用 Undo)
9. Undo 调优
9.1 大小
-- 推荐
ALTER SYSTEM SET undo_retention = 3600;
-- 计算所需
SELECT
ROUND((SELECT MAX(begin_time) FROM v$undostat) -
(SELECT MIN(begin_time) FROM v$undostat)) AS hours,
ROUND(SUM(undoblks) / COUNT(*) * 4 / 1024, 2) AS undo_size_gb
FROM v$undostat;
9.2 自动调优
- 11g+ 自动
- 90% 表空间用于活跃事务
- 10% 用于 retention
9.3 GUARANTEE
- 保证 retention
- 可能空间不足
- 谨慎使用
10. 监控
10.1 v$undostat
SELECT
TO_CHAR(begin_time, 'YYYY-MM-DD HH24:MI') AS begin_time,
undoblks,
txncount,
maxquerylen,
maxconcurrency,
ssolderrcnt,
nospaceerrcnt
FROM v$undostat
ORDER BY begin_time DESC;
10.2 v$transaction
SELECT
addr,
xid,
status,
start_time,
used_ublk,
used_urec
FROM v$transaction;
10.3 大小
SELECT
tablespace_name,
ROUND(sum(bytes) / 1024 / 1024 / 1024, 2) AS gb
FROM dba_data_files
WHERE tablespace_name LIKE 'UNDO%'
GROUP BY tablespace_name;
11. 多 Undo 表空间
11.1 RAC
-- 每节点独立
ALTER SYSTEM SET undo_tablespace = undotbs1 SID='orcl1';
ALTER SYSTEM SET undo_tablespace = undotbs2 SID='orcl2';
11.2 切换
-- 1. 创建新
CREATE UNDO TABLESPACE undotbs2 DATAFILE '...' SIZE 10G;
-- 2. 切换
ALTER SYSTEM SET undo_tablespace = undotbs2;
-- 3. 删除旧
DROP TABLESPACE undotbs1 INCLUDING CONTENTS;
12. 闪回与 Undo
12.1 Flashback Query
SELECT * FROM employees
AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' HOUR);
12.2 Flashback Version
SELECT versions_xid, versions_starttime, salary
FROM employees
VERSIONS BETWEEN TIMESTAMP
(SYSTIMESTAMP - INTERVAL '1' HOUR) AND SYSTIMESTAMP;
12.3 Flashback Transaction
SELECT * FROM flashback_transaction_query
WHERE xid = HEXTORAW('...');
详细见:Oracle 闪回技术。
13. 常见坑与排错
13.1 ORA-01555
- Undo 不足
- 增大 undo_retention
- 增大 Undo 表空间
- GUARANTEE
13.2 ORA-30036
- 表空间满
- 增大表空间
- 优化大事务
13.3 ORA-01552
- 系统表空间缺 Undo
- 创建 Undo 表空间
14. 最佳实践
- AUM:自动
- retention 充足:闪回
- 大小监控:避免满
- RAC 独立:避免竞争
- GUARANTEE 谨慎:闪回关键
- 监控 v$undostat:调优
- 大事务监控:避免爆
- 闪回测试:可行
- 定期评估:调整
- 文档化:配置
15. 参考资料
[1] Oracle Database Administrator’s Guide 19c, “Undo” https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/undo.html