【数据库管理】⑦管理undo

1. undo的概述和作用

在Oracle数据库中,undo是一种用于实现事务回滚和读一致性的机制。当一个事务对数据库进行修改时,Oracle会将修改前的数据保存到undo表空间中,以便在需要回滚事务或者读取一致性数据时使用。

undo的作用主要有以下几个方面:

  1. 实现事务回滚:当一个事务需要回滚时,Oracle会使用undo中保存的修改前的数据来还原数据库到事务开始之前的状态。

  2. 实现读一致性:当一个事务正在执行时,其他事务需要读取数据时,Oracle会使用undo中保存的修改前的数据来保证读取的数据是一致的。

  3. 支持闪回查询:闪回查询是一种可以在不恢复整个数据库的情况下,快速还原数据库到某个时间点的查询方式。Oracle会使用undo中保存的数据来实现闪回查询。

  4. 支持多版本并发控制:多版本并发控制是一种可以让多个事务同时访问数据库而不会相互干扰的机制。Oracle会使用undo中保存的数据来实现多版本并发控制。

总之,undo是Oracle数据库中非常重要的一个机制,它可以实现事务回滚、读一致性、闪回查询和多版本并发控制等功能。在实际应用中,需要根据实际情况来配置undo表空间的大小和性能,以保证数据库的稳定性和性能。

对数据执行修改操作时(DML修改buffer cache里的数据块),数据库会生成undo 信息(对当前的块的旧镜像信息做个保存,保存的块就是undo块),一旦执行的事务或语句由于某种原因失败,或者发出一条ROLLBACK 语句请求回滚,就可以利用undo信息将数据放回到修改前的样子.undo 信息存储在一组特殊的段中,这称为undo 段(undo segment).

[oracle@oracle-db-19c ~]$ sqlplus / as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Mon Apr 3 08:05:51 2023
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle.  All rights reserved.


Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0

SQL> show user
USER is "SYS"
SQL> set pagesize 200 linesize 200
SQL> 
SQL>
SQL> col tablespace_name format a20
SQL> col status format a20
SQL> select segment_name, tablespace_name, status, block_id, file_id from dba_rollback_segs;

SEGMENT_NAME         TABLESPACE_NAME      STATUS                 BLOCK_ID    FILE_ID
-------------------- -------------------- -------------------- ---------- ----------
SYSTEM               SYSTEM               ONLINE                      128          1
_SYSSMU1_1261223759$ UNDOTBS1             ONLINE                      128          4
_SYSSMU2_27624015$   UNDOTBS1             ONLINE                      144          4
_SYSSMU3_2421748942$ UNDOTBS1             ONLINE                      160          4
_SYSSMU4_625702278$  UNDOTBS1             ONLINE                      176          4
_SYSSMU5_2101348960$ UNDOTBS1             ONLINE                      192          4
_SYSSMU6_813816332$  UNDOTBS1             ONLINE                      208          4
_SYSSMU7_2329891355$ UNDOTBS1             ONLINE                      224          4
_SYSSMU8_399776867$  UNDOTBS1             ONLINE                      240          4
_SYSSMU9_1692468413$ UNDOTBS1             ONLINE                      256          4
_SYSSMU10_930580995$ UNDOTBS1             ONLINE                      272          4

11 rows selected.

SQL> 

 

使用undo tablespace 存放从datafiles 读出的数据块的前镜像,提供以下四种情况所需要的信息.
1).回滚事务 :rollback

2).读一致性 :正在做DML操作的数据块,事务结束前,其他用户读undo里面的数据前镜像

3).实例恢复 :instance recover(undo -------->rollback)

4).闪回技术 :flashback query、flashback table等

2. undo的管理模式

-- Manual 	:roll segment(淘汰)
-- Auto 	:undo tablespace (init parameter :undo_management=auto)

SQL> 
SQL> show parameter undo

NAME                                 TYPE                              VALUE
------------------------------------ --------------------------------- ------------------------------
temp_undo_enabled                    boolean                           FALSE
undo_management                      string                            AUTO
undo_retention                       integer                           900
undo_tablespace                      string                            UNDOTBS1
SQL> 

3. 查看当前的undo TBS

-- UNDOTBS1的10个段,10个大表,系统默认10个

SQL> 
SQL> show parameter undo

NAME                                 TYPE                              VALUE
------------------------------------ --------------------------------- ------------------------------
temp_undo_enabled                    boolean                           FALSE
undo_management                      string                            AUTO
undo_retention                       integer                           900
undo_tablespace                      string                            UNDOTBS1
SQL> select * from v$rollname;

       USN NAME                                                                                           CON_ID
---------- ------------------------------------------------------------------------------------------ ----------
         0 SYSTEM                                                                                              1
         1 _SYSSMU1_1261223759$                                                                                1
         2 _SYSSMU2_27624015$                                                                                  1
         3 _SYSSMU3_2421748942$                                                                                1
         4 _SYSSMU4_625702278$                                                                                 1
         5 _SYSSMU5_2101348960$                                                                                1
         6 _SYSSMU6_813816332$                                                                                 1
         7 _SYSSMU7_2329891355$                                                                                1
         8 _SYSSMU8_399776867$                                                                                 1
         9 _SYSSMU9_1692468413$                                                                                1
        10 _SYSSMU10_930580995$                                                                                1

11 rows selected.

SQL> 

4. 建立undo tablespace

1).可以建立多个undo tablespace(缺省一个),但一个时刻只有一个处于active

2).处于active状态的undo tablespace 不能offline 和 drop

SQL> 
SQL> select tablespace_name, status, contents from dba_tablespaces;

TABLESPACE_NAME      STATUS               CONTENTS
-------------------- -------------------- ---------------------------------------------------------------
SYSTEM               ONLINE               PERMANENT
SYSAUX               ONLINE               PERMANENT
UNDOTBS1             ONLINE               UNDO
TEMP                 ONLINE               TEMPORARY
USERS                ONLINE               PERMANENT
TEMP02               ONLINE               TEMPORARY

6 rows selected.

SQL> SELECT file_name FROM dba_data_files WHERE tablespace_name = 'UNDOTBS1';

FILE_NAME
----------------------------------------
/u02/oradata/CDB1/undotbs01.dbf

SQL>

SQL> CREATE UNDO TABLESPACE UNDOTBS2 DATAFILE '/u02/oradata/CDB1/undotbs02.dbf' SIZE 100M AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED;

Tablespace created.

SQL> select tablespace_name, status, contents from dba_tablespaces;

TABLESPACE_NAME      STATUS               CONTENTS
-------------------- -------------------- ---------------------------------------------------------------
SYSTEM               ONLINE               PERMANENT
SYSAUX               ONLINE               PERMANENT
UNDOTBS1             ONLINE               UNDO
TEMP                 ONLINE               TEMPORARY
USERS                ONLINE               PERMANENT
UNDOTBS2             ONLINE               UNDO
TEMP02               ONLINE               TEMPORARY

7 rows selected.

SQL> 

5. 切换undo tablespace

SQL> 
SQL> -- memory动态修改
SQL> alter system set undo_tablespace=undotbs2;

System altered.

SQL> show parameter undo

NAME                                 TYPE                              VALUE
------------------------------------ --------------------------------- ------------------------------
temp_undo_enabled                    boolean                           FALSE
undo_management                      string                            AUTO
undo_retention                       integer                           900
undo_tablespace                      string                            UNDOTBS2
SQL> select * from v$rollname;

       USN NAME                                                                                           CON_ID
---------- ------------------------------------------------------------------------------------------ ----------
         0 SYSTEM                                                                                              1
        11 _SYSSMU11_4263211716$                                                                               1
        12 _SYSSMU12_4060389560$                                                                               1
        13 _SYSSMU13_1614986827$                                                                               1
        14 _SYSSMU14_2442247673$                                                                               1
        15 _SYSSMU15_3040896203$                                                                               1
        16 _SYSSMU16_2151182073$                                                                               1
        17 _SYSSMU17_1110798109$                                                                               1
        18 _SYSSMU18_2692559868$                                                                               1
        19 _SYSSMU19_79700264$                                                                                 1
        20 _SYSSMU20_1318461731$                                                                               1
        21 _SYSSMU21_2969415316$                                                                               1
        22 _SYSSMU22_3147182066$                                                                               1
        23 _SYSSMU23_208810255$                                                                                1

14 rows selected.

SQL>  alter system set undo_tablespace=undotbs1;

System altered.

SQL> show parameter undo

NAME                                 TYPE                              VALUE
------------------------------------ --------------------------------- ------------------------------
temp_undo_enabled                    boolean                           FALSE
undo_management                      string                            AUTO
undo_retention                       integer                           900
undo_tablespace                      string                            UNDOTBS1
SQL> select * from v$rollname;

       USN NAME                                                                                           CON_ID
---------- ------------------------------------------------------------------------------------------ ----------
         0 SYSTEM                                                                                              1
         1 _SYSSMU1_1261223759$                                                                                1
         2 _SYSSMU2_27624015$                                                                                  1
         3 _SYSSMU3_2421748942$                                                                                1
         4 _SYSSMU4_625702278$                                                                                 1
         5 _SYSSMU5_2101348960$                                                                                1
         6 _SYSSMU6_813816332$                                                                                 1
         7 _SYSSMU7_2329891355$                                                                                1
         8 _SYSSMU8_399776867$                                                                                 1
         9 _SYSSMU9_1692468413$                                                                                1
        10 _SYSSMU10_930580995$                                                                                1

11 rows selected.

SQL> 

6. 删除undo tablespace

SQL> 
SQL> drop tablespace undotbs2 including contents and datafiles;

Tablespace dropped.

SQL> -- 动态视图查看
SQL> select * from v$tablespace;

       TS# NAME                                                                                       INCLUDED_ BIGFILE   FLASHBACK ENCRYPT_I     CON_ID
---------- ------------------------------------------------------------------------------------------ --------- --------- --------- --------- ----------
         1 SYSAUX                                                                                     YES       NO        YES                          1
         0 SYSTEM                                                                                     YES       NO        YES                          1
         2 UNDOTBS1                                                                                   YES       NO        YES                          1
         4 USERS                                                                                      YES       NO        YES                          1
         3 TEMP                                                                                       NO        NO        YES                          1
         0 SYSTEM                                                                                     YES       NO        YES                          2
         1 SYSAUX                                                                                     YES       NO        YES                          2
         2 UNDOTBS1                                                                                   YES       NO        YES                          2
         3 TEMP                                                                                       NO        NO        YES                          2
         0 SYSTEM                                                                                     YES       NO        YES                          3
         1 SYSAUX                                                                                     YES       NO        YES                          3
         2 UNDOTBS1                                                                                   YES       NO        YES                          3
         3 TEMP                                                                                       NO        NO        YES                          3
         5 USERS                                                                                      YES       NO        YES                          3
         0 SYSTEM                                                                                     YES       NO        YES                          4
         1 SYSAUX                                                                                     YES       NO        YES                          4
         2 UNDOTBS1                                                                                   YES       NO        YES                          4
         3 TEMP                                                                                       NO        NO        YES                          4
         5 USERS                                                                                      YES       NO        YES                          4
        14 TEST_TBS                                                                                   YES       NO        YES                          3
        15 PANDAS_TBS                                                                                 YES       NO        YES                          3
         6 TEMP02                                                                                     NO        NO        YES                          3
         6 TEMP02                                                                                     NO        NO        YES                          1
         7 DATA01                                                                                     YES       NO        YES                          3
         8 TBS_MAXWELL                                                                                YES       NO        YES                          3
         9 TEMP_MAXWELL                                                                               NO        NO        YES                          3
        10 UNDOTBS2                                                                                   YES       NO        YES                          3
        11 TBS_TOOLS                                                                                  YES       NO        YES                          3
         5 USERS                                                                                      YES       NO        YES                         12
        13 RMAN1                                                                                      YES       NO        YES                          3
         0 SYSTEM                                                                                     YES       NO        YES                         12
         1 SYSAUX                                                                                     YES       NO        YES                         12
         2 UNDOTBS1                                                                                   YES       NO        YES                         12
         3 TEMP                                                                                       NO        NO        YES                         12

34 rows selected.

SQL> 

7. undo数据块的4种状态

在Oracle数据库中,undo数据块有以下4种状态:

  1. Dirty状态表示该undo数据块中的数据已经被修改但是还没有被写入磁盘当事务提交时,Oracle会将Dirty状态的undo数据块写入磁盘。

  2. Unexpired状态表示该undo数据块中的数据还没有过期,可以用于读取一致性数据或者回滚事务。当undo数据块中的所有事务都已经提交或者回滚时,该undo数据块就会变为Unexpired状态。

  3. Expired状态表示该undo数据块中的数据已经过期,不能再用于读取一致性数据或者回滚事务。当undo数据块中的某个事务占用的undo数据块已经达到了undo_retention参数设置的时间限制时,该undo数据块就会变为Expired状态。

  4. Stale状态表示该undo数据块中的数据已经被覆盖,不能再用于读取一致性数据或者回滚事务。当undo数据块中的数据被新的事务修改时,该undo数据块就会变为Stale状态。

需要注意的是,undo数据块的状态会随着事务的提交、回滚和过期而不断变化。在实际应用中,需要根据实际情况来配置undo表空间的大小和性能,以保证数据库的稳定性和性能。同时,还需要定期监控undo表空间的使用情况,以及进行undo表空间的维护和优化。

 

undo retention参数和undo autoextend on特性

*undo retention参数规定了unexpired commit数据的保留期,*它是保证一致性读和大多数闪回技术成功的关键,

将undo tbs设为autoextend on, 这是DBCA创建数据库时的缺省设置, *这一个特性将在 undo**空间不足时优先扩展新的空间,*其次才是覆盖unexpired commit.

NOTE: 如果要减少ORA_O1555错误(snapshot too old),考虑延长undo retention或使能 undo autoextend on.

8. Undo Retention Period

Undo Retention Period是Oracle数据库中一个重要的参数,用于控制undo数据的保留时间。当一个事务对数据库进行修改时,Oracle会将修改前的数据保存到undo表空间中,以便在需要回滚事务或者读取一致性数据时使用。Undo Retention Period参数指定了undo数据在undo表空间中保留的时间,超过这个时间的undo数据将被自动删除。

Undo Retention Period参数的默认值是900秒(15分钟),可以通过以下SQL语句查询和修改:

查询Undo Retention Period参数的值:

SQL> col value format a20
SQL> SELECT value FROM v$parameter WHERE name = 'undo_retention';

VALUE
--------------------
900

SQL> 

修改Undo Retention Period参数的值:

SQL> ALTER SYSTEM SET undo_retention = 1800;

System altered.

SQL> SELECT value FROM v$parameter WHERE name = 'undo_retention';

VALUE
--------------------
1800

SQL> 

上述语句将Undo Retention Period参数的值修改为1800秒(30分钟)。

需要注意的是,修改Undo Retention Period参数的值可能会影响数据库的性能和稳定性。如果Undo Retention Period参数设置得太小,可能会导致undo数据被过早地删除,从而导致事务回滚失败或者读取不一致的数据。如果Undo Retention Period参数设置得太大,可能会导致undo表空间的空间不足,从而导致事务失败。因此,在修改Undo Retention Period参数的值时,需要根据实际情况进行调整,并进行充分的测试和验证。

9. Retention Guarantee 

Retention Guarantee是Oracle数据库中一个可选的参数,用于保证undo数据在undo表空间中的最小保留时间。当Retention Guarantee参数设置为TRUE时,Oracle会保证undo数据在undo表空间中的最小保留时间,即使undo表空间空间不足或者undo数据被过早地删除也不会影响保留时间。当Retention Guarantee参数设置为FALSE时,Oracle会尽可能地保留undo数据,但是不能保证最小保留时间。

Retention Guarantee参数的默认值是FALSE,可以通过以下SQL语句查询和修改:

查询Retention Guarantee参数的值: 


SQL> SELECT value FROM v$parameter WHERE name = 'undo_retention';

VALUE
--------------------
900

SQL> 

修改Retention Guarantee参数的值:

ALTER SYSTEM SET undo_retention = 1800 RETENTION GUARANTEE;

该语句将Retention Guarantee参数的值修改为1800秒(30分钟),并启用保证最小保留时间的功能。

需要注意的是,启用Retention Guarantee参数可能会导致undo表空间的空间不足,从而导致事务失败。因此,在启用Retention Guarantee参数时,需要确保undo表空间有足够的空间,并进行充分的测试和验证。同时,还需要定期监控undo表空间的使用情况,以及进行undo表空间的维护和优化。

9.1 查看retention guarantee

通过dba_tablespaces视图, 缺省配置下undo retention是noguarantee.

SQL> select tablespace_name, status, contents, retention from dba_tablespaces;

TABLESPACE_NAME      STATUS               CONTENTS                                                        RETENTION
-------------------- -------------------- --------------------------------------------------------------- ---------------------------------
SYSTEM               ONLINE               PERMANENT                                                       NOT APPLY
SYSAUX               ONLINE               PERMANENT                                                       NOT APPLY
UNDOTBS1             ONLINE               UNDO                                                            NOGUARANTEE
TEMP                 ONLINE               TEMPORARY                                                       NOT APPLY
USERS                ONLINE               PERMANENT                                                       NOT APPLY
TEMP02               ONLINE               TEMPORARY                                                       NOT APPLY

6 rows selected.

SQL>

9.2 启用retention guarantee

在使用create database、create undo tablespace建立时开启,或使用alter tablespace修改retention guarantee选项;

SQL> 
SQL> -- 保证在retention期间不允许被覆盖
SQL> show user;
USER is "SYS"
SQL> show con_name;

CON_NAME
------------------------------
CDB$ROOT
SQL> alter tablespace UNDOTBS1 retention guarantee;

Tablespace altered.

SQL> select tablespace_name,status ,contents,retention from dba_tablespaces;

TABLESPACE_NAME      STATUS               CONTENTS                                                        RETENTION
-------------------- -------------------- --------------------------------------------------------------- ---------------------------------
SYSTEM               ONLINE               PERMANENT                                                       NOT APPLY
SYSAUX               ONLINE               PERMANENT                                                       NOT APPLY
UNDOTBS1             ONLINE               UNDO                                                            GUARANTEE
TEMP                 ONLINE               TEMPORARY                                                       NOT APPLY
USERS                ONLINE               PERMANENT                                                       NOT APPLY
TEMP02               ONLINE               TEMPORARY                                                       NOT APPLY

6 rows selected.

SQL> 

9.3 禁用retention guarantee

SQL> alter tablespace undotbs1 retention noguarantee;

Tablespace altered.

SQL> select tablespace_name,status ,contents,retention from dba_tablespaces;

TABLESPACE_NAME      STATUS               CONTENTS                                                        RETENTION
-------------------- -------------------- --------------------------------------------------------------- ---------------------------------
SYSTEM               ONLINE               PERMANENT                                                       NOT APPLY
SYSAUX               ONLINE               PERMANENT                                                       NOT APPLY
UNDOTBS1             ONLINE               UNDO                                                            NOGUARANTEE
TEMP                 ONLINE               TEMPORARY                                                       NOT APPLY
USERS                ONLINE               PERMANENT                                                       NOT APPLY
TEMP02               ONLINE               TEMPORARY                                                       NOT APPLY

6 rows selected.

SQL> 

综合以上两点所述,针对undo_retention这个参数,个人的理解如下:
 

1).undo_retention只是一个预期结果,数据库会尽量达到的这个目标,但实际的结果可能优于预期(撤销空间足够充足),也可能低于预期(撤销空间不足);

2).当撤销 TBS充足时,所有的撤销数据都被保留在撤销空间内.已提交的撤销数据只会被标记为"过期" (并不删除).在空间不足时,它们才可以被新事务的撤销数据所覆盖,未提交的事务被标记为"未过期";

3).当撤销 TBS不足时,首先去覆盖标记为”过期”的撤销数据,如果此时还是空间不足,新的事务还是会覆盖未过期的撤销数据的,毕竟新事务不可能一直等待旧事务的提交或回滚完成后才发生;

4).如果在撤销 TBS上指定了retention guarantee,在撤销空间不足且旧的事务的撤销数据未过期时,将会由于无法分配撤销空间而导致新的事务的执行失败;

这个属性只对已commit的undo状态有效

10. undo信息查询

1).v$session 查看用户建立的session

2).v$transaction 当前的事务

3).v$rollname undo段的名称

4).v$rollstat undo段的状态

5).dba_rollback_segs 数据字典里记录的undo段状态

一般来说,一个session只能对应一个事务,建立了session未必有事务,只有事务处于活动状态时,v$transaction才能看到这个事务.换句话说,如果看到了事务(在 v$transaction 里),那一定有个session和它对应,将两个视图里连在一起,信息看得更为清楚.

10.1 产生一个session

SQL> col username format a20
SQL> select username,sid,serial# from v$session where username is not null;

USERNAME                    SID    SERIAL#
-------------------- ---------- ----------
SYS                           2      26630
SYS                         257      24339
SCOTT                       260      15876

SQL> show user;
USER is "SYS"
SQL> show con_name;

CON_NAME
------------------------------
PDB1
SQL> 

10.2 产生一个事务

SQL> show user;
USER is "SCOTT"
SQL> create table emp1 as select * from emp;

Table created.

SQL> select * from emp1;

     EMPNO ENAME                          JOB                                MGR HIREDATE               SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- --------------- ---------- ---------- ----------
      7369 SMITH                          CLERK                             7902 17-DEC-80              800                    20
      7499 ALLEN                          SALESMAN                          7698 20-FEB-81             1600        300         30
      7521 WARD                           SALESMAN                          7698 22-FEB-81             1250        500         30
      7566 JONES                          MANAGER                           7839 02-APR-81             2975                    20
      7654 MARTIN                         SALESMAN                          7698 28-SEP-81             1250       1400         30
      7698 BLAKE                          MANAGER                           7839 01-MAY-81             2850                    30
      7782 CLARK                          MANAGER                           7839 09-JUN-81             2450                    10
      7788 SCOTT                          ANALYST                           7566 24-JAN-87             3000                    20
      7844 TURNER                         SALESMAN                          7698 08-SEP-81             1500          0         30
      7876 ADAMS                          CLERK                             7788 02-APR-87             1100                    20
      7900 JAMES                          CLERK                             7698 03-DEC-81              950                    30
      7902 FORD                           ANALYST                           7566 03-DEC-81             3000                    20
      7934 MILLER                         CLERK                             7782 23-JAN-82             1300                    10
      7839 KING                           PRESIDENT                         8000 17-NOV-81             5000          0         10

14 rows selected.

SQL> update emp1 set comm=800 where empno=7788;

1 row updated.

SQL> 

10.3 联合查询session和事务

SQL> select a.sid,a.serial#,a.username,b.xidusn,xidslot,b.ubablk,b.status from v$session a,v$transaction b where a.saddr=b.ses_addr;
SID	SERIAL#	USERNAME	XIDUSN	XIDSLOT	UBABLK	STATUS
---	-------	--------	------	-------	------	-------
23	50042	SCOTT		20		20		274		ACTIVE
-- 两表联查
-- sid和serial#在v$session里
-- 在v$transaction里:
	-- XIDUSN是undo segment的id,
	-- XIDSLOT是事务槽的id,
	-- UBABLK是undo块号
-- 对照上面看,下面语句显示出_SYSSMU20是一个活动段, 与XIDUSN=20吻合, 说明这个段被读进buffer了.
SQL> select a.usn,b.name,a.xacts from v$rollstat a, v$rollname b where a.usn=b.usn;
USN	NAME					CON_ID
---	---------------------	-------
0	SYSTEM				0
11	_SYSSMU11_4042378425$	0
12	_SYSSMU12_2010754074$	0
13	_SYSSMU13_3885018169$	0
14	_SYSSMU14_2215206726$	0
15	_SYSSMU15_2246797103$	0
16	_SYSSMU16_1518052737$	0
17	_SYSSMU17_1675921924$	0
18	_SYSSMU18_2474130580$	0
19	_SYSSMU19_193690114$	0
20	_SYSSMU20_118432001$	1
21	_SYSSMU21_1311937374$	0
22	_SYSSMU22_1028642511$	0
-- 说明上面的update操作用了13张表里的第20张表

11. system undo tbs

默认system TBS会有一个单独的 undo segment(usn为 0).其他 TBS的事务不能使用它.

缺省下undo tablespace 会被分配10个undo segment,理论上一个段可以有多个事务,但Oracle的策略并不情愿如此,实验表明,对应并发的事务,通常每个事务会分配一个UNDO 段,也就是说如果这10个段不够,Oracle会自动再增加段.

当数据库启动时,如果碰到undo数据文件损坏或不同步,可以将其offline, 即只有一个系统 TBS(system)的undo也能进入系统,使数据字典得以维护,但不能对其他 TBS做DML操作.

12. undo损坏和修复

数据库open下undo损坏和修复

如果数据库打开的情况下,当前undo坏掉的话,比如现在UNDOTBS2出现了介质损坏,那么数据库就不能继续DML操作了.如果这时UNDOTBS2 TBS上还有active状态的事务(未提交),Oracle会将其下的所有段(10个段)都标志为NEEDS RECOVERY,这时有备份可以恢复这个UNDOTBS2,但如果没有备份,你需要用新建的UNDO替代损坏的UNDO,那么损坏UNDO上的未提交事务也将丢弃.但Oracle没有提供自动解决NEEDS RECOVERY的机制,如果你想删除这个损坏的UNDO TBS,必须另做处理(需要系统择时重启),我们模拟一下这种情况:

12.1 删除undo tbs

[oracle@oracle-db-19c CDB1]$ pwd
/u02/oradata/CDB1
[oracle@oracle-db-19c CDB1]$ ll undo*
-rw-r-----. 1 oracle oinstall 382738432 Apr  3 09:18 undotbs01.dbf
[oracle@oracle-db-19c CDB1]$ mv undotbs01.dbf undotbs01.dbf.bkp
[oracle@oracle-db-19c CDB1]$ ll undo*
-rw-r-----. 1 oracle oinstall 382738432 Apr  3 09:19 undotbs01.dbf.bkp
[oracle@oracle-db-19c CDB1]$ 

12.2 DML操作失败

SQL> alter system checkpoint;
-- cmd端再做update 语句时会报错
SQL> update emp1 set sal=1000 where empno=7902;
ORA-01116:   打开数据库文件 3 时出错
ORA-01110:   数据文件 8:   '/u01/app/oracle/oradata/orcl/undotbs02.dbf'
ORA-27041:   无法打开文件

12.3 shutdown immediate

SQL> shutdown immediate

12.4 Startup启动失败

SQL> startup
ORACLE instance started.
Total System Global Area 2466250752 bytes
Fixed Size			2927384 bytes
Variable Size		654312680 bytes
Database Buffers		1795162112 bytes
Redo Buffers		13848576 bytes
Database mounted.
ORA-01157: cannot identify/lock data file 8 - see DBWR trace file
ORA-01110: data file 8: '/u01/app/oracle/oradata/orcl/undotbs02.dbf'

12.5 启动到mount状态下

 数据库open之前要检查所记录SCN和datafile heaer记录的SCN是否一致;一致就正常打开库,不一致需要做media recover.

 

SQL> startup force mount
SQL> startup mount
SQL> select file#,checkpoint_change# from v$datafile;
FILE#	CHECKPOINT_CHANGE#
------	----------------------
1		8476730
2		8476730
3		8476730
5		8476730
6		8476730
7		8476730
8		8476730
SQL> select file#,checkpoint_change# from v$datafile_header;
FILE#	CHECKPOINT_CHANGE#
------	----------------------
1		8476730
2		8476730
3		8476730
5		8476730
6		8476730
7		8476730
8		0

12.6 将undo tbs offline

SQL> alter database datafile 8 offline;
Database altered.

12.7 Database open

SQL> alter database open;
Database altered.

12.8 依旧查不到undo tbs

SQL> select * from v$rollname;
USN	NAME	CON_ID
---	-------	---------
0	SYSTEM	0
-- 	这个静态视图可以列出所有(online或offline)UNDO段信息
SQL> select segment_name,status from dba_rollback_segs;
SEGMENT_NAME			STATUS
--------------------	-------------
SYSTEM					ONLINE
_SYSSMU22_1028642511$	NEEDS RECOVERY
_SYSSMU21_1311937374$	NEEDS RECOVERY
_SYSSMU20_118432001$	NEEDS RECOVERY
_SYSSMU19_193690114$	NEEDS RECOVERY
_SYSSMU18_2474130580$	NEEDS RECOVERY
_SYSSMU17_1675921924$	NEEDS RECOVERY
_SYSSMU16_1518052737$	NEEDS RECOVERY
_SYSSMU15_2246797103$	NEEDS RECOVERY
_SYSSMU14_2215206726$	NEEDS RECOVERY
_SYSSMU13_3885018169$	NEEDS RECOVERY
_SYSSMU12_2010754074$	NEEDS RECOVERY
_SYSSMU11_4042378425$	NEEDS RECOVERY
-- DML依旧无法操作

12.9 Create新的undo tbs

 

SQL> create undo tablespace undotbs1 datafile '/u01/app/oracle/oradata/orcl/undotbs01.dbf' size 100m autoextend on;
Tablespace created.
SQL> select * from v$tablespace;
TS#	NAME	INC	BIG	FLA	ENC	CON_ID
---	-------	---	---	---	---	------
1	SYSAUX	YES	NO	YES		0
0	SYSTEM	YES	NO	YES		0
2	UNDOTBS1YES	NO	YES		0	-- 需要激活
4	USERS	YES	NO	YES		0
3	TEMP	NO	NO	YES		0
6	EXAMPLE	YES	NO 	YES		0
5	UNDOTBS2YES	NO	YES		0	-- 文件已经被改名
SQL> select * from v$rollname;
USN	NAME	CON_ID
---	-------	---------
0	SYSTEM	0

12.10 Alter激活新的undo tbs

SQL> alter system set undo_tablespace=UNDOTBS1;
SQL> show parameter undo
NAME				TYPE	VALUE
------------------	-------	---------
temp_undo_enabled	boolean	FALSE
undo_management		string	AUTO
undo_retention		integer	900
undo_tablespace		string	UNDOTBS1

 12.11 删除原已有事务的undo tbs

注意: 此时原有活动事务的信息(未提交)可能仍然保存在UNDOTBS2, 已经没有恢复的必要了.

先删掉UNDOTBS2,否则无法使用UNDOTBS1

12.11.1 删除报错分析

SQL> drop tablespace undotbs2 including contents and datafiles; 
drop tablespace undotbs2 including contents and datafiles
*
ERROR at line 1:
ORA-01548: active rollback segment '_SYSSMU11_4042378425$' found, terminate dropping tablespace
-- ORA-01548: 已找到活动回退段 '_SYSSMU11_4042378425$', 终止删除 TBS
-- 无法删除UNDOTBS2是因为undotbs2中有事务,Oracle把其下的所有段都标志成 NEEDS RECOVERY了,再查看一下相关的数据字典:
SQL> select segment_name,status from dba_rollback_segs;
SEGMENT_NAME			STATUS
--------------------	---------------
SYSTEM					ONLINE
_SYSSMU24_1145560925$	ONLINE
_SYSSMU23_497753519$	ONLINE
_SYSSMU10_3531180387$	ONLINE
_SYSSMU9_2948221526$	ONLINE
_SYSSMU8_77629217$		ONLINE
_SYSSMU7_4210038832$	ONLINE
_SYSSMU6_2365516946$	ONLINE
_SYSSMU5_42966806$		ONLINE
_SYSSMU4_2369906140$	ONLINE
_SYSSMU3_3546637655$	ONLINE
_SYSSMU2_3335685343$	ONLINE
_SYSSMU1_1652837430$	ONLINE
_SYSSMU22_1028642511$	NEEDS RECOVERY
_SYSSMU21_1311937374$	NEEDS RECOVERY
_SYSSMU20_118432001$	NEEDS RECOVERY
_SYSSMU19_193690114$	NEEDS RECOVERY
_SYSSMU18_2474130580$	NEEDS RECOVERY
_SYSSMU17_1675921924$	NEEDS RECOVERY
_SYSSMU16_1518052737$	NEEDS RECOVERY
_SYSSMU15_2246797103$	NEEDS RECOVERY
_SYSSMU14_2215206726$	NEEDS RECOVERY
_SYSSMU13_3885018169$	NEEDS RECOVERY
_SYSSMU12_2010754074$	NEEDS RECOVERY
_SYSSMU11_4042378425$	NEEDS RECOVERY
25 rows selected.

解决有两个办法:

12.11.2 方法一、使用备份恢复

12.11.3 方法二、使用 oracle 提供的隐含参数_CORRUPTED_ROLLBACK_SEGMENTS

12.11.3.1 用spfile建立静态参数文件


SQL> create pfile from spfile;
[oracle@oracle-db-19c CDB1]$ cd $ORACLE_HOME/dbs
[oracle@oracle-db-19c dbs]$ pwd
/u01/app/oracle/product/19.3.0/dbhome_1/dbs
[oracle@oracle-db-19c dbs]$ ls -ltr
total 116964
-rw-r--r--. 1 oracle oinstall     3079 May 14  2015 init.ora.bkp
-rw-r--r--. 1 oracle oinstall     3079 May 14  2015 init.ora
-rw-r-----. 1 oracle oinstall       24 Nov  2 15:03 lkCDB1
-rw-r-----. 1 oracle oinstall     3584 Nov 27 16:55 spfilecdb1.ora.bkp
-rw-r-----. 1 oracle oinstall     3072 Feb  1 13:41 orapwcdb1
-rw-r--r--. 1 oracle oinstall     1188 Feb  2 19:19 initcdb1.ora.bkp
-rw-r--r--. 1 oracle oinstall     1188 Feb  2 19:19 initcdb1.ora
-rw-r-----. 1 oracle oinstall 14018048 Apr  2 15:48 arch1_400_1119711914.dbf
-rw-r-----. 1 oracle oinstall 34015232 Apr  2 16:00 arch1_401_1119711914.dbf
-rw-rw----. 1 oracle oinstall     1544 Apr  2 16:08 hc_cdb1.dat
-rw-r-----. 1 oracle oinstall  1843712 Apr  2 16:08 arch1_402_1119711914.dbf
-rw-r-----. 1 oracle oinstall 31752704 Apr  3 08:03 arch1_403_1119711914.dbf
-rw-r-----. 1 oracle oinstall 18989056 Apr  3 08:31 snapcf_cdb1.f
-rw-r-----. 1 oracle oinstall 19103744 Apr  3 08:31 c-1093429351-20230403-00
-rw-r-----. 1 oracle oinstall     3584 Apr  3 08:38 spfilecdb1.ora
[oracle@oracle-db-19c dbs]$ 

12.11.3.2 编辑静态参数文件

[oracle@oracle-db-19cdbs]$ vi  initcdb1.ora
# 在静态参数文件里第一行插入以下10个needs recovery段的内容
_CORRUPTED_ROLLBACK_SEGMENTS=
(_SYSSMU22_1028642511$,
_SYSSMU21_1311937374$,
_SYSSMU20_118432001$,
_SYSSMU19_193690114$,
_SYSSMU18_2474130580$,
_SYSSMU17_1675921924$,
_SYSSMU16_1518052737$,
_SYSSMU15_2246797103$,
_SYSSMU14_2215206726$,
_SYSSMU13_3885018169$,
_SYSSMU12_2010754074$,
_SYSSMU11_4042378425$)

12.11.3.3 使静态参数文件启动数据库

SQL> shutdown immediate
SQL> startup pfile=$ORACLE_HOME/dbs/initorcl.ora

12.11.3.4 删除回退段

......
SQL> 
drop rollback segment "_SYSSMU22_1028642511$";
drop rollback segment "_SYSSMU21_1311937374$";
drop rollback segment "_SYSSMU20_118432001$";
drop rollback segment "_SYSSMU19_193690114$";
drop rollback segment "_SYSSMU18_2474130580$";
drop rollback segment "_SYSSMU17_1675921924$";
drop rollback segment "_SYSSMU16_1518052737$";
drop rollback segment "_SYSSMU15_2246797103$";
drop rollback segment "_SYSSMU14_2215206726$";
drop rollback segment "_SYSSMU13_3885018169$";
drop rollback segment "_SYSSMU12_2010754074$";
drop rollback segment "_SYSSMU11_4042378425$";

12.11.3.5 查验

-- 至此可以正常DML等操作
SQL> select segment_name,status from dba_rollback_segs;
SEGMENT_NAME			STATUS
---------------------	------
SYSTEM					ONLINE
_SYSSMU24_1145560925$	ONLINE
_SYSSMU23_497753519$	ONLINE
_SYSSMU10_3531180387$	ONLINE
_SYSSMU9_2948221526$	ONLINE
_SYSSMU8_77629217$		ONLINE
_SYSSMU7_4210038832$	ONLINE
_SYSSMU6_2365516946$	ONLINE
_SYSSMU5_42966806$		ONLINE
_SYSSMU4_2369906140$	ONLINE
_SYSSMU3_3546637655$	ONLINE
_SYSSMU2_3335685343$	ONLINE
_SYSSMU1_1652837430$	ONLINE

12.11.3.6 删除undotbs2

SQL> select * from v$tablespace;
TS#	NAME	INC	BIG	FLA	ENC	CON_ID
---	-------	---	---	---	---	--------
1	SYSAUX	YES	NO	YES		0
0	SYSTEM	YES	NO	YES		0
2	UNDOTBS1YES	NO	YES		0 
4	USERS	YES	NO	YES		0
3	TEMP	NO	NO	YES		0
6	EXAMPLE	YES	NO 	YES		0
5	UNDOTBS2YES	NO	YES		0	-- 文件已经被改名
SQL> drop tablespace undotbs2 including contents and datafiles;
Tablespace dropped.
-- 如果还删除不了,则尝试修改字典
select * from v$tablespace;
-- 记下要删除的undo对应的ts#号,比如是=2,则执行下行语句:
update seg$ set type# = 3 where ts#=2;
-- 然后再删除该 TBS即可.

13. 临时Undo TBS

13.1 概述

Temporary Undo表空间Oracle数据库中的一种特殊类型的Undo表空间,用于存储临时Undo数据。它与普通Undo表空间的区别在于,它不会被用于长期存储Undo数据,而是只用于存储临时Undo数据,这些数据在事务提交后就会被立即删除。

Temporary Undo表空间的作用是提高数据库的性能和可用性。可以减少Undo表空间的使用量,从而减少数据库的I/O负载和存储空间占用。同时,它还可以提高数据库的可用性,因为它可以避免长时间的事务占用Undo表空间,从而导致其他事务无法执行的情况。

在Oracle数据库中,Temporary Undo表空间是可选的,可以根据实际情况来配置。如果数据库中存在大量的长时间事务,或者Undo表空间的使用量较大,可以考虑配置Temporary Undo表空间来提高数据库的性能和可用性。同时,还需要定期监控Temporary Undo表空间的使用情况,以及进行Temporary Undo表空间的维护和优化。

启用 temp undo 好处:

1).减少 undo TBS

2).减少 redo 数据

3).允许在ADG中对临时表进行DML操作

13.2 启用

-- session级别
SQL> ALTER SESSION SET TEMP_UNDO_ENABLED=TRUE;
SQL> ALTER SESSION SET TEMP_UNDO_ENABLED=FALSE;
-- system级别:
SQL> ALTER SYSTEM SET TEMP_UNDO_ENABLED=TRUE;
SQL> ALTER SYSTEM SET TEMP_UNDO_ENABLED=FALSE;

你可能感兴趣的:(Oracle,Administration,数据库,oracle,java)