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. 最佳实践

  1. AUM:自动
  2. retention 充足:闪回
  3. 大小监控:避免满
  4. RAC 独立:避免竞争
  5. GUARANTEE 谨慎:闪回关键
  6. 监控 v$undostat:调优
  7. 大事务监控:避免爆
  8. 闪回测试:可行
  9. 定期评估:调整
  10. 文档化:配置

15. 参考资料

[1] Oracle Database Administrator’s Guide 19c, “Undo” https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/undo.html