65-Oracle Undo机制

前一期看了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. 存储架构

层级结构:​
  1. Undo表空间:专用存储容器
  2. 数据文件:物理存储文件(如undotbs01.dbf)
  3. 回滚段:每个事务绑定独立段
  4. 区(Extents):8个连续块组成的分配单元
  5. 块(Blocks):标准8KB Oracle块
  6. Undo记录:实际存储单元
空间状态管理:​
  • 活动区(Active)​​:事务进行中,强制保留
  • 未过期区(Unexpired)​​:已提交+保留期内,优先保留
  • 过期区(Expired)​​:超保留期,可覆盖使用

3. 写入流程

  1. DML操作触发Undo记录生成
  2. Undo记录写入Buffer Cache
  3. 同步生成Redo日志(Write-Ahead Logging)
  4. LGWR进程将Redo写入日志文件
  5. DBWn进程异步将Undo数据写入磁盘
  6. 事务提交时更新状态

三、关键配置与管理策略

1. 核心参数配置

-- 基础配置 --
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. 表空间管理

​创建表空间:​

CREATE UNDO TABLESPACE undotbs2DATAFILE '/opt/oracle/oradata/FREE/FREEPDB1/undotbs2_01.dbf' SIZE 20GAUTOEXTEND ON NEXT 1G MAXSIZE UNLIMITEDRETENTION GUARANTEE;  -- 关键系统启用保证模式

​空间维护操作:​ 

-- 空间回收
ALTER TABLESPACE undotbs1 SHRINK SPACE KEEP 15G;
-- 表空间切换
ALTER SYSTEM SET UNDO_TABLESPACE = undotbs2;
-- 删除旧表空间
DROP TABLESPACE undotbs1 INCLUDING CONTENTS AND DATAFILES;

3. 监测体系

​空间压力监控:​

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;

​事务级监控:​ 

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

​文件级监控:​ 

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. 读一致性验证

--会话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. 保留期保证验证 
-- 设置保留保证
ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;-- 生成测试数据并等待超保留期
BEGINUPDATE 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性能验证 
-- 启用临时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效果验证
-- 检查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
-- 生成负载测试
DECLARECURSOR c_emp IS SELECT * FROM HR.employees FOR UPDATE;
BEGINFOR r IN c_emp LOOPUPDATE HR.employees SET salary = salary * 1.01 WHERE CURRENT OF c_emp;END LOOP;COMMIT;
END;
/
-- 再次检查IMU统计

五、最佳实践指南

1. 容量规划公式

所需空间(GB) = (DPM × ARS × UR) / (1024³) × 1.5
  • DPM​:每分钟DML操作数
  • ARS​:平均行大小(字节)
  • UR​:保留期(分钟)
  • 1.5​:安全系数(含元数据开销)

2. 高可用架构设计

多表空间轮换策略
  • 创建至少两个Undo表空间
  • 定期切换:ALTER SYSTEM SET UNDO_TABLESPACE=undotbs2;
  • 保留旧表空间24小时后删除
空间保障策略
-- 关键系统启用保留保证
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机制通过多阶段技术演进,已从基础的事务回滚工具发展为支持多版本控制、闪回操作和多租户、云原生优化的综合数据管理平台。关键最佳实践包括:
  1. 根据业务负载科学规划空间容量
  2. OLTP系统启用IMU和临时Undo
  3. 关键业务启用RETENTION GUARANTEE
  4. 建立多层次监控预警体系
  5. 定期进行健康检查和性能优化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/85793.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/85793.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ESP32摄像头开发实例】-实现遥控视频小车

ESP32-CAM实现遥控视频小车 文章目录 ESP32-CAM实现遥控视频小车1、硬件准备2、代码实现3、代码解析4、程序下载到开发板在本文中,将详细介绍如何使用ESP32-CAM制作一辆Wi-Fi远程控制的小车。 1、硬件准备 在开始这个项目之前,我们将强调用于构建机器人的最重要的特性和组件…

图片加载优化(缩略图)

缩略图 系统目前的问题:首页直接加载原图,原图文件通常比缩略图大数倍甚至数十倍,不仅导致加载时间长,还会造成大量流量浪费。 解决方案:上传图片时,同时生成一份较小尺寸的缩略图。用户浏览图片列表时加…

GO语言---数组

文章目录 数组的基本特性数组的声明和初始化数组元素的访问和操作数组遍历多维数组数组的长度和容量数组作为函数参数数组与切片的区别注意 数组是Go语言中最基本的数据结构之一,它是一组相同类型元素的固定长度序列。 数组的基本特性 1、固定长度:数组…

7.5.3_1处理冲突的方法-拉链法

知识总览: 拉链法: 开始散列表中没有存储任何数据元素即散列地址上的元素是空的,散列地址可以视为链表的头指针,即没有插入任何元素前链表的头指针是空的。一个散列地址对应一个链表,散列地址上实际没有存数据元素&am…

鸿蒙运动项目开发:项目运行环境切换器

##鸿蒙核心技术##运动开发# 在开发鸿蒙运动项目时,管理不同运行环境(如开发环境、测试环境、生产环境)是一个常见的需求。通过合理地切换运行环境,开发者可以方便地进行调试、测试和部署。本文将介绍如何实现一个项目运行环境切换…

Linux内核中安全创建套接字:为何inet_create未导出及正确替代方案

引言 在Linux内核开发中,当驱动程序需要创建网络套接字时,开发者常会遇到一个关键问题:核心函数inet_create(负责初始化IPv4套接字)并未导出到内核符号表。本文深入剖析这一设计决策背后的逻辑,并提供驱动程序安全创建套接字的实践方案。 一、inet_create未导出的深层原…

63、不同路径II

题目 解答: 初始化和特殊情况比较麻烦的dp obstacleGrid(0,0)1的,直接return 0即可。入口都被堵住了还怎么走。 mn1情况,直接判断 第一行初始化:dp[1][0]->dp[i][0] 碰到有障碍物的,从当前格子开始到末尾全部置…

wx小程序登录设置角色

背景。pc端登录后在访问业务链接时可以根据固定获取用户的方法LoginUser user LoginHelper.getLoginUser(); 获取到用户信息。但wx端登录后无法获取。原因处在登陆时对用户信息的设置方面pc端和小程序端登录没有使用相同的登录方法。排除得知wx端小程序登录时没有设置角色。所…

MySQL5.7 慢查询SQL语句集合

文章目录 1. 按平均执行时间排序的慢查询2. 按总执行时长排序的慢查询3. MySQL 5.7 慢查询配置检查4. 扫描行数分析(找出全表扫描)5. 高频执行的慢查询6. 当前正在执行的查询7. 慢查询统计汇总8. 表结构和索引分析8.1 表索引详情查询8.2 表大小统计 1. 按…

MySQL学习(1)——基础库操作

欢迎来到博主的专栏:MySQL学习 博主ID:代码小豪 文章目录 数据库原理基础库操作增删数据库数据库编码与校验规则验证不同的校验规则对于库中数据的影响 备份与恢复数据库 数据库原理 mysql版本:mysql8.0 操作系统:ubuntu22.4 为了减少由于环境配置以及权限限制带来的使用问题&…

C++法则12:右值引用的核心目的:支持移动语义(Move Semantics)

C法则12:右值引用的核心目的:支持移动语义(Move Semantics) 右值引用(Rvalue Reference)是C11引入的最重要特性之一,其主要设计目的就是支持移动语义(Move Semantics)。 …

【LLM学习笔记4】使用LangChain开发应用程序(上)

目录 前言一、模型、提示和解析器(model、prompt、parsers)二、储存三、模型链四、基于文档的问答1.使用向量存储查询2. 结合表征模型和向量存储使用检索问答链回答问题 前言 在前面两部分,我们分别学习了大语言模型的基础使用准则&#xff…

Negative Contrastive Estimation Negative Sampling

1. 基本概念与问题背景 1.1 大规模分类问题 在自然语言处理中,给定上下文 c c c预测单词 w w w的条件概率为: P ( w ∣ c ) exp ⁡ ( s θ ( w , c ) ) ∑ w ′ ∈ V exp ⁡ ( s θ ( w ′ , c ) ) P(w|c) \frac{\exp(s_\theta(w,c))}{\sum_{w\in V…

Flink SQL Connector Kafka 核心参数全解析与实战指南

Flink SQL Connector Kafka 是连接Flink SQL与Kafka的核心组件,通过将Kafka主题抽象为表结构,允许用户使用标准SQL语句完成数据读写操作。本文基于Apache Flink官方文档(2.0版本),系统梳理从表定义、参数配置到实战调优…

vscode内嵌浏览器实时预览vue项目

安装插件 web Preview 启动vue项目 打开预览 ctrl shift p 之后输入并选择 Open Web Preview 即可看到预览窗口,但此时明明我的页面是有内容的,但是窗口却空白的。 因为默认访问端口是3000,我们将其修改为vue项目默认的5173端口即可。 点…

计算机网络:(四)物理层的基本概念,数据通信的基础知识,物理层下面的传输媒体

计算机网络:(四)物理层的基本概念,数据通信的基础知识,物理层下面的传输媒体 前言一、物理层的基本概念1. 什么是物理层2. 物理层的核心使命3. 物理层的四大特性 二、数据通信的基础知识1. 数据通信系统的基本模型1.1 …

Linux系统性能优化

目录 Linux系统性能优化 一、性能优化概述 二、性能监控工具 1. 基础工具 2. 高级工具 三、子系统优化策略 1. CPU优化 2. 内存优化 3. 磁盘I/O优化 4. 网络优化 四、资源限制优化 1. ulimit 2. cgroups(控制组) 五、安全与注意事项 六、…

【streamlit streamlit中 显示 mermaid 流程图有两种方式】

streamlit中显示mermaid 流程图有两种方式 mermaind示例 code """ flowchart LRmarkdown["This **is** _Markdown_"]newLines["Line1Line 2Line 3"]markdown --> newLinesmarkdown["This **is** _Markdown_"]newLines[&quo…

Rust调用 DeepSeek API

Rust 实现类似 DeepSeek 的搜索工具 使用 Rust 构建一个高效、高性能的搜索工具需要结合异步 I/O、索引结构和查询优化。以下是一个简化实现的框架: 核心组件设计 索引结构 use std::collections::{HashMap, HashSet}; use tantivy::schema::{Schema, TEXT, STORED}; use …

Unity3D仿星露谷物语开发69之动作声音

1、目标 Player动作时产生的声音,比如砍倒树木、砸石头。 2、修复NPC快速行进的bug(与本节无关) 修改NPCMovement.cs脚本的MoveToGridPositionRoutine方法。 确保npcCalculatedSpeed的速度不少于最慢速度。 原代码: 修改后的…