从 oracle 11g 开始, 如果使用的是默认安装方式, 数据库就无需 DBA 干预而会自动管理 undo; 如果在安装过程中勾选了 oracle flashback 操作选项, 就需要执行一些管理 undo 的任务来保证 flashback 操作能够成功执行.
oracle 数据库创建以及管理用来回滚, 撤销, 改变数据库的信息. 这些信息包括事务中所有操作的记录, 主要是提交前的记录. 这些记录统称为 undo
undo 记录用于:
1. Roll back transactions when a ROLLBACK statement is issued 回滚事务
2. Recover the database 恢复数据库
3. Provide read consistency 提供一致性读
4. Analyze data as of an earlier point in time by using Oracle Flashback Query 使用 flashback 查询分析之前任意时间点的数据
5. Recover from logical corruptions using Oracle Flashback features 使用 flashback 特性恢复数据库的逻辑损坏(逻辑讹误)
When a ROLLBACK statement is issued, undo records are used to undo changes that were made to the database by the uncommitted transaction. During database recovery, undo records are used to undo any uncommitted changes applied from the redo log to the data files. Undo records provide read consistency by maintaining the before image of the data for users who are accessing the data at the same time that another user is changing it.
当执行 rollabck 语句时, undo 记录用于撤销未提交事务对数据库进行的修改. 在数据库恢复的过程中, undo 记录根据 redo log 上的记录将数据文件中的未提交的更新还原回来, 当用户正在查询数据而同时另一个用户正在修改相应的数据时, Undo 记录通过保留一份更改前的数据镜像来保证一致性读
2.1 automatic undo management 简介
从 oracle 11g 开始, 新安装的数据库中自动 undo 管理将是默认的模式, 当你使用 dbca 创建数据库的时候, 一个自动扩展的名为 undotbs1 的 undo 表空间将会自动创建.
当实例启动后, 数据库会自动选用第一个可用的 undo 表空间, 如果没有可用的 undo 表空间, 实例将会把 undo 记录保存在 system 表空间, 并且在警告日志文件中会有警告信息提示当前系统正运行在没有 undo 表空间的环境中.【系统不推荐】
AUM 有两个主要的初始化参数
undo_management | 如果是 AUTO 或者是 null, 代表启用了自动 undo 管理 如果是 MANUAL, 代表采用手动管理 undo 默认值为 AUTO |
undo_tablespace | 可选的值, 只在自动 undo 管理模式下有效, 指定 undo 表空间的名字 |
当启动了 Automatic undo management, 涉及到手动 undo 管理的初始化参数将被忽略
2.2 关于 Undo Retention Period(撤销数据保存时间 / 数据过期时间)
当事务提交后, undo 数据将不需要回滚或者事务恢复. 然而为了数据库一致性读, 一些查询时间长的查询语句可能需要一些旧的 undo 数据来获取 block 的前镜像. 此外, oracle flashback 特性也将依靠这些可用的旧的 undo 数据. 因此, 尽可能长的保存这些旧的 undo 数据将是非常有用的.
当启动了自动 undo 管理时, 通常就会涉及到 undo retention period(撤销数据保存期), undo retention period 指的是 undo 已经提交过的数据过期时间.
undo_retention 默认值是 900 秒. 如果 undo 表空间已经写满并且不可扩展, 新事务的数据就会去覆盖已经已经提交的 undo 数据, 不管这些数据是否已经过期;此外, undo 表空间的数据如果已经过期, 已经提交事务的 undo 数据只是失效, 只要没有被新事务的数据覆盖就还会存在, 还可以被 flashback 使用.
oracle 数据库会根据 undo tablespace 的配置情况自动调整 undo retention period(撤销数据保存时间 / 数据过期时间)
如果 undo tablespace 设置为 AUTOEXTEND
自动扩展, 数据库会动态的调整 undo_retention 的值, 使它大于当前系统运行时间最长的查询时间. 然而, 这种调整方式不一定能够满足 oracle flashback 的操作. Oracle Flashback 操作返回的 “snapshot
too
old" 错误提示就说明当前的 undo 数据不够不足以支持此项操作. 为了更好的满足
Oracle Flashback 特性, 你可以设置 undo_retention 参数的值等于Oracle Flashback 操作所期望的最大值, 也可以把 undo 表空间设置为固定大小.
如果 undo 表空间是固定大小, 数据库会根据 undo 表空间大小以及系统负载自动调整数据过期时间(undo retention period), 最佳的数据过期时间通常比 longest-running 的查询的时间大
如果你决定把 undo 表空间转为固定大小, 你必须设定 undo 表空间的大小为一个尽可能大的值. 如果你的设定的 undo 表空间的大小太小, 将会出现以下两类错误:
DML 操作失败, 因为没有足够大的空间来容纳新事务的 undo 数据
Long-running 查询语句查询失败并且返回 “snnapshot too old” 的错误提示, 因为没有足够的 undo 数据来保证一致性读
2.3 retention guarantee
为了保证 long-running 的查询语句以及 flashback 操作能够成功执行, 可以启用 retention guarantee. 如果启用了 retention guarantee, 指定的 undo_retention (最小的 undo 数据过期的时间) 将会得到保证, 如果 undo 表空间大小不足, 数据库宁可返回错误也不会去覆盖 undo 表空间中没有过期的 undo 数据. 如果没有启用 retention guarantee, 当 undo 表空间大小不足时数据库就会去覆盖即使没有过期的 undo 数据, 因而间接就缩短了 undo_retention 数据过期时间的大小. 数据库默认选项为不启用 retention guarantee.
-- 注意, 启用 retention guarantee 可能导致多个 DML 操作失败
可以在 create database 或者 create undo tablespace 语句中增加 retention grarantee 语句指定启用 retention guarantee. 也可以使用 alter tablespace 中指定启用还是禁用.
启用 retention guarantee
alter tablespace undotbs1 retention guarantee;
禁用 retention guarantee
alter tablespace undotbs1 retention noguarantee;
在 dba_tablespaces 中 retention 字段可以查询到 undo 表空间 retention guarantee 的设置, retention 取值为guarantee / noguarantee / not apply, 其中如果不是 undo 表空间的表空间都是 not apply.
SQL> select tablespace_name, retention from dba_tablespaces;
TABLESPACE_NAME RETENTION
------------------------------ -----------
SYSTEM NOT APPLY
SYSAUX NOT APPLY
UNDOTBS1 NOGUARANTEE
TEMP NOT APPLY
USERS NOT APPLY
SCOTT_TBS NOT APPLY
For a fixed-size undo tablespace, the database calculates the best possible retention based on database statistics and on the size of the undo tablespace. For optimal undo management, rather than tuning based on 100% of the tablespace size, the database tunes the undo retention period based on 85% of the tablespace size, or on the warning alert threshold percentage for space used, whichever is lower. (The warning alert threshold defaults to 85%, but can be changed.) Therefore, if you set the warning alert threshold of the undo tablespace below 85%, this may reduce the tuned size of the undo retention period. For more information on tablespace alert thresholds, see"Managing Tablespace Alerts".
对于固定大小的 undo 表空间, 数据库会根据统计信息以及 undo 表空间的大小自动估算最佳的 retention(数据过期时间). 管理 undo 最佳的情况并不是根据 100% 的 undo 表空间大小来估算, 而是根据 85% 的 undo 表空间大小与设定的空间警告提示的阈值, 这两者中的最小值来估算的.
可以通过查询 v$undostat 中的 tuned_undoretention 字段来查看当前 retention 的变化, v$undostat 这个视图包含最近四天每隔10分钟自动采集的数据(如果要查询超过四天的数据, 就用 dba_hist_undostat). tuned_undoretention 的单位为秒
SQL> select to_char(begin_time, 'yyyy/mm/dd hh24:mi') begin_name, to_char(end_ti
me, 'yyyy/mm/dd hh24:mi') end_time,
2 tuned_undoretention
3 from v$undostat
4 order by end_time desc;
BEGIN_NAME END_TIME TUNED_UNDORETENTION
---------------- ---------------- -------------------
2014/11/17 13:14 2014/11/17 13:17 1457
2014/11/17 13:04 2014/11/17 13:14 1336
2014/11/17 12:54 2014/11/17 13:04 1940
2014/11/17 12:44 2014/11/17 12:54 1340
2014/11/17 12:34 2014/11/17 12:44 1943
2014/11/17 12:24 2014/11/17 12:34 1343
2014/11/17 12:14 2014/11/17 12:24 1947
2014/11/17 12:04 2014/11/17 12:14 1348
2014/11/17 11:54 2014/11/17 12:04 1951
设定 undo_retention 的方法
UNDO_RETENTION = 1800
ALTER SYSTEM SET UNDO_RETENTION = 2400;
对于固定大小的 undo 表空间, 自动调整 undo_retention(数据过期时间)通常会取得更好的结果, 如果你决定设定 undo 表空间为固定大小, 那么 undo advisor 可以帮助你估算 undo_retention 的大小. 可以通过 OEM 或者通过 dbms_advisor pl / sql 包来查看 undo advisor. 通常建议使用 OEM 查看
Undo advisor 是通过 Automatic Workload Repository (AWR) 收集的统计信息来计算 undo_retention 的大小, 因此 AWR 的信息对于 undo advisor 提供一个准确的建议值非常重要. 对于新建的数据库, 可能统计信息还没有收集好, 因此, 继续使用默认的自动扩展的 undo 表空间直到负载统计信息收集完成
使用 Undo Advisor 前, 需要估算以下两个值:
最长查询的时间, 在系统运转一段周期后, 你可以在 System Activity subpage of the Automatic Undo Management page 中 看到运行时间最长的查询
需要 flashback 的最长间隔
执行 undo advisor 并不会改变 undo 表空间的大小, 它只是仅仅给你一个建议, 要更改表空间的数据文件大小必须使用 alter database 语句
SQL> ALTER DATABASE DATAFILE '/oracle/dbs/undotbs.dbf' RESIZE 300M;
SQL> ALTER DATABASE DATAFILE '/oracle/dbs/undotbs.dbf' AUTOEXTEND OFF;
通过 PL / SQL 创建 advisor 任务来激活 undo advisor(Undo 顾问)
下面的分析是根据 Automatic workload repository snapshots(AWR)而来, 必须设定 start_snapshot 和 end_snapshot 两个参数
DECLARE tid NUMBER; tname VARCHAR2(30); oid NUMBER; BEGIN DBMS_ADVISOR.CREATE_TASK('Undo Advisor', tid, tname, 'Undo Advisor Task'); DBMS_ADVISOR.CREATE_OBJECT(tname, 'UNDO_TBS', null, null, null, 'null', oid); DBMS_ADVISOR.SET_TASK_PARAMETER(tname, 'TARGET_OBJECTS', oid); DBMS_ADVISOR.SET_TASK_PARAMETER(tname, 'START_SNAPSHOT', 1); DBMS_ADVISOR.SET_TASK_PARAMETER(tname, 'END_SNAPSHOT', 2); DBMS_ADVISOR.SET_TASK_PARAMETER(tname, 'INSTANCE', 1); DBMS_ADVISOR.execute_task(tname); END; /
创建完这个 advisor task, 可以 OEM 中的 ADDR 内 或者 DBA_ADVISOR_* (DBA_ADVISOR_TASKS
,DBA_ADVISOR_OBJECTS
,DBA_ADVISOR_FINDINGS
,DBA_ADVISOR_RECOMMENDATIONS
等) 数据字典中看到输出结果以及建议
3.1 创建 undo 表空间
创建 undo 表空间有两种方式:
在 undo 表空间中不能创建其他的数据库对象, undo 表空间只保存系统的 undo 数据
SQL> CREATE UNDO TABLESPACE undotbs_02 DATAFILE '/u01/oracle/rbdb1/undo0201.dbf' SIZE 2M REUSE AUTOEXTEND ON;
可以创建多个 undo 表空间, 但是在同一时间内只有一个表空间是 active
3.2 修改 undo 表空间
Undo tablespaces are altered using the ALTER TABLESPACE statement. However, since most aspects of undo tablespaces are system managed, you need only be concerned with the following actions:
SQL> ALTER TABLESPACE undotbs_01 ADD DATAFILE '/u01/oracle/rbdb1/undo0102.dbf' AUTOEXTEND ON NEXT 1M MAXSIZE UNLIMITED;
3.3 删除 undo 表空间
SQL> drop tablespace undotbs_01;
undo 表空间只能在当前没有被实例使用的情况下才能被删除. 如果 undo 表空间包含 outstanding transactions(例如, 事务发生异常中断但还没有回滚), 删除表空间就会失败. 删除 undo 表空间一定要很小心, 因为会自动删除还没有过期的 undo 信息.
删除 undo 表空间
drop tablespace … 执行结果同 DROP TABLESPACE...INCLUDING CONTENTS 一样, 所有内容将被删除
.
drop tablespace undotbs_01 = drop tablespace undotbs_01 including contents;
3.4 switch undo 表空间
因为 undo_tablespace 初始化参数是一个动态参数, 可以使用 alter system set 语句指定一个新的 undo 表空间
SQL> ALTER SYSTEM SET UNDO_TABLESPACE = undotbs_02;
假设当前的 undo 表空间是 undotbs_01, 当上面的语句执行成功后, 当前实例将会使用 undotbs_02 代替 undotbs_01作为当前实例的 undo tablespace
当满足以下任意一个条件时, 转换 undo 表空间就出现错误
The database is online while the switch operation is performed, and user transactions can be executed while this command is being executed. When the switch operation completes successfully, all transactions started after the switch operation began are assigned to transaction tables in the new undo tablespace.
切换 undo 表空间并不影响用户事务的执行, 当切换操作成功后, switch 操作之后所有事务产生的 undo 数据将会保存在新的 undo 表空间
The switch operation does not wait for transactions in the old undo tablespace to commit. If there are any pending transactions in the old undo tablespace, the old undo tablespace enters into aPENDING OFFLINE
mode (status). In this mode, existing transactions can continue to execute, but undo records for new user transactions cannot be stored in this undo tablespace.
切换表空间操作并不会等待旧的 undo 空间上所有的事务都提交. 如果在旧的 undo 表空间上还有事务在执行, 那么旧的 undo 表空间状态变为 pending offline. 在这个模式下, 已经存在的事务继续执行, 但是产生的 undo 数据不能保存在这个 undo 表空间中.
An undo tablespace can exist in this PENDING OFFLINE
mode, even after the switch operation completes successfully. APENDING OFFLINE
undo tablespace cannot be used by another instance, nor can it be dropped. Eventually, after all active transactions have committed, the undo tablespace automatically goes from thePENDING OFFLINE
mode to theOFFLINE
mode. From then on, the undo tablespace is available for other instances (in an Oracle Real Application Cluster environment).
即使切换操作执行完成, 旧的 undo 表空间(状态为 pending offline) 不能被其他实例使用也不能删除. 最后, 当旧的 undo 表空间上所有的事务都提交后, 它的状态从 pending offline 变为 offline. 这时, 旧的 undo 表空间可以被其他实例使用(RAC环境)
3.5 undo space 有关的数据字典 view
v$undostat | Contains statistics for monitoring and tuning undo space. Use this view to help estimate the amount of undo space required for the current workload. The database also uses this information to help tune undo usage in the system. This view is meaningful only in automatic undo management mode |
v$rollstat | For automatic undo management mode, information reflects behavior of the undo segments in the undo tablespace |
v$transaction | contains undo segment imformation dba_undo_extents: Shows the status and size of each extent in the undo tablespace |
dba_hist_undostat | Contains statistical snapshots of V$UNDOSTAT information |
参考: https://docs.oracle.com/cd/E11882_01/server.112/e25494/undo.htm#ADMIN013