Oracle 18c 管理可恢复空间分配

管理可恢复空间分配
Oracle 数据库提供了一种机制,可在空间分配失败时暂停大型数据库操作的执行,并在之后恢复执行。因此,您可以采取纠正措施,而无需 Oracle 数据库服务器向用户返回错误。在错误条件修复后,被暂停的操作将自动恢复。此功能称为可恢复的空间分配,受影响的语句称为可恢复语句。

可恢复空间分配是如何工作的
可恢复空间分配的工作原理如下:
1.只有当执行语句的会话通过以下操作之一启用了可恢复空间分配功能时,语句才会以可恢复模式执行。
.当RESUMABLE_TIMEOUT初始化参数设置为非零值时,在执行语句之前,在会话中发出ALTER SESSION ENABLE RESUMABLE语句。

.ALTER SESSION ENABLE RESUMABLE TIMEOUT timeout_value语句在语句执行之前在会话中发出,且timeout_value是非零值。

2.当出现以下条件之一时,将挂起可恢复语句(这些条件会导致不可恢复语句发出相应的错误信号):
.超出空间状态

.达到的最大范围条件

.空间配额超出条件。

3.当可恢复语句的执行被挂起时,有一些机制可以执行用户提供的操作、记录错误和查询语句执行的状态。当一个可恢复语句被挂起时,将执行 以下操作:
.在警报日志中报告错误。

.系统发出恢复会话挂起警报。

.如果用户在后挂起系统事件上注册了触发,则执行用户触发。用户提供的PL/SQL过程可以使用DBMS_RESUMABLE包和DBA_或USER_RESUMABLE视图 来访问错误消息数据。

4.暂停语句会自动导致暂停事务。因此,所有事务资源都通过语句suspend和resume保存。

5.当错误条件解决后(例如,由于用户干预或其他查询释放的排序空间),暂停的语句自动恢复执行,可恢复的会话暂停警报被清除。

6.被挂起的语句可以使用DBMS_RESUMABLE.ABORT()过程强制抛出异常。DBA或发出语句的用户可以调用这个过程。

7.挂起超时时间间隔由初始化参数resume able_timeout或ALTER SESSION ENABLE resume timeout语句中的timeout值指定,与resume语句相关 联。如果错误条件没有在超时时间内解决,则暂停为超时时间的resume语句将被唤醒并向用户返回异常。

8.可恢复语句在执行过程中可以多次挂起和恢复。

哪些操作是可恢复的?
以下操作可以恢复:
.查询
用完临时空间(对于排序区域)的SELECT语句是可恢复执行的候选语句。当使用OCI时,调用ocstmtexecute()和OCIStmtFetch()是候选的。

.DML
INSERT、UPDATE 和 DELETE 语句都是候选对象。执行这些语句所使用的接口并不重要,可以是 OCI、PL/SQL 或其他接口。此外,从外部表中 INSERT INTO…SELECT 的操作也可以恢复。

.导入/导出
SQL*Loader,一个命令行参数控制语句是否在可恢复错误后恢复。

.DDL
以下语句是可恢复执行的候选语句:

– CREATE TABLE ... AS SELECT
– CREATE INDEX
– ALTER INDEX ... REBUILD
– ALTER TABLE ... MOVE PARTITION
– ALTER TABLE ... SPLIT PARTITION
– ALTER INDEX ... REBUILD PARTITION
– ALTER INDEX ... SPLIT PARTITION
– CREATE MATERIALIZED VIEW
– CREATE MATERIALIZED VIEW LOG

哪些错误是可以纠正的?
可纠正的错误有三类:
.超出空间状态
该操作不能为表空间中的表/索引/临时段/undo段/集群/LOB/表分区/索引分区获取更多的extent。例如,下列错误就属于这种类型:

ORA-01653 unable to extend table ... in tablespace ...
ORA-01654 unable to extend index ... in tablespace ...

.达到的最大范围条件
表/索引/临时段/undo段/ cluster/LOB/表分区/索引分区中的extent数量等于该对象上定义的最大extent数量。例如,下列错误就属于这种类型 :

ORA-01631 max # extents ... reached in table ...
ORA-01632 max # extents ... reached in index ...

.空间配额超出条件
用户在表空间中超过分配的空间配额。具体来说,下面的错误指出了这一点:

ORA-01536 space quote exceeded for tablespace string

可恢复空间分配和分布式操作
在分布式环境中,如果用户启用或禁用了可恢复空间分配,或者DBA修改了resume able_timeout初始化参数,那么本地实例就会受到影响。无法远程启用resume。

在分布式事务中,远程实例上的会话只有在远程实例已经在其站点上启用了resumeable时才被挂起。

并行执行和可恢复空间分配
在并行执行中,如果其中一个并行执行服务器进程遇到可纠正的错误,则该服务器进程暂停其执行。

其他并行执行的服务器进程将继续执行各自的任务,直到遇到错误或被暂停的服务器进程阻塞(直接或间接)为止。当可纠正的错误解决后,挂 起的进程恢复执行,并行操作继续执行。如果被挂起的操作终止,那么并行操作将中止,并向用户抛出错误。

不同的并行执行服务器进程可能会遇到一个或多个可纠正的错误。这可能导致并行地多次触发AFTER SUSPEND触发器。此外,如果一个并行执行 服务器进程遇到不可纠正的错误,而另一个并行执行服务器进程被挂起,则挂起的语句立即中止。

对于并行执行,每个并行执行协调器和服务器进程在DBA_或USER_RESUMABLE视图中都有自己的条目。

启用和禁用可恢复空间分配
通过运行SQL语句和设置某些初始化参数,可以启用和禁用可恢复空间分配。

关于启用和禁用可恢复空间分配
只有当语句在启用了恢复模式的会话中执行时,才可能进行可恢复空间分配。

当执行ALTER SESSION ENABLE RESUMABLEe语句时,启用会话的resume空间分配,并且将该会话的resumeable_timeout初始化参数设置为非零值 。当在系统级别设置resum_timeout初始化参数时,ALTER SESSION ENABLE RESUMABLE语句默认不指定超时值。当ALTER SESSION ENABLE RESUMABLE语句指定超时值时,它会覆盖系统默认值。

当执行ALTER SESSION ENABLE RESUMABLE语句时,在以下所有情况下都会禁用会话的可恢复空间分配:
.会话不会执行ALTER SESSION ENABLE RESUMABLE语句。

.会话执行ALTER SESSION DISABLE RESUMABLE语句。

.会话执行ALTER SESSION DISABLE RESUMABLE语句,超时值为0。
由于挂起的语句会占用一些系统资源,因此在允许用户启用可恢复空间分配和执行可恢复语句之前,必须授予用户RESUMABLE系统特权。

设置RESUMABLE_TIMEOUT初始化参数
你可以通过设置RESUMABLE_TIMEOUT初始化参数来指定一个默认的系统范围的超时时间。

例如,在初始化参数文件中的RESUMABLE_TIMEOUT参数设置为1小时:
RESUMABLE_TIMEOUT = 3600

如果这个参数设置为0,那么即使会话运行了没有超时值的ALTER SESSION ENABLE RESUMABLE语句也会禁用可恢复空间分配。

也可以使用ALTER SYSTEM SET语句在系统级别修改该参数的值。例如,下面的语句对所有运行了没有超时值ALTER SESSION ENABLE RESUMABLE语句的会话禁用resume空间分配:

SQL> ALTER SYSTEM SET RESUMABLE_TIMEOUT=0;

System altered.

使用ALTER SESSION来启用和禁用可恢复空间分配
在会话中,用户可以使用ALTER SESSION SET语句设置RESUMABLE_TIMEOUT初始化参数,并启用可恢复空间分配、更改超时值或禁用可恢复模式。

用户可以使用以下SQL语句并使用系统默认设置的RESUMABLE_TIMEOUT值为会话启用恢复模式:

SQL> ALTER SESSION ENABLE RESUMABLE;

Session altered.

要禁用恢复模式,用户发出以下语句:

SQL> ALTER SESSION DISABLE RESUMABLE;

Session altered.

默认情况下,新会话的恢复模式是禁用的。用户还可以指定超时间隔,并提供用于标识可恢复语句的名称。

指定超时时间
当您启用恢复模式时,您可以设置一个超时时间,如果没有发生任何干预,则挂起的语句将出错。

下面的语句指定可恢复的事务将在3600秒后超时并出错:

SQL> ALTER SESSION ENABLE RESUMABLE TIMEOUT 3600;

Session altered.

TIMEOUT的值在被另一个ALTER SESSION ENABLE RESUMABLE语句修改之前一直有效,或者被其他方法修改,或者会话结束。如果没有设置 RESUMABLE_TIMEOUT初始化参数,那么使用ENABLE RESUMABLE TIMEOUT子句启用恢复模式时,默认的超时时间是7200秒。

命名可恢复语句
可恢复语句可以通过名称来标识。下面的语句为可恢复语句分配一个名称:

SQL> ALTER SESSION ENABLE RESUMABLE TIMEOUT 3600 NAME 'insert into table';

Session altered.

NAME值一直有效,直到被另一个ALTER SESSION ENABLE RESUMABLE语句修改,或者会话结束。NAME的默认值是“用户username(userid),会话 sessionid,实例instanceid”。

语句名用于标识DBA_RESUMABLE和USER_RESUMABLE视图中的resumable语句。

使用LOGON触发器设置默认的可恢复模式
除了设置RESUMABLE_TIMEOUT初始化参数之外,另一种设置默认恢复模式的方法是,你可以注册一个数据库级别的登录触发器来改变用户的会话 以启用恢复并设置一个超时间隔。

检测暂停语句
当一个可恢复的语句被挂起时,不会向客户端抛出错误。为了采取纠正措施,Oracle数据库提供了通知用户错误和提供有关情况的信息的替代方 法。

通知用户:AFTER SUSPEND系统事件和触发器
当可恢复语句遇到可纠正的错误时,系统内部会生成AFTER SUSPEND系统事件。用户可以在数据库和模式级别为该事件注册触发器。如果用户注 册一个触发器来处理此系统事件,则在SQL语句挂起之后执行该触发器。

在AFTER SUSPEND触发器中执行的SQL语句总是不可恢复的,并且总是自治的。在触发器内启动的事务使用SYSTEM回滚段。施加这些条件是为了克 服死锁并减少触发器遇到与语句相同的错误条件的机会。

用户可以使用USER_RESUMABLE或DBA_RESUMABLE视图,DBMS_RESUMABLE。SPACE_ERROR_INFO函数,在触发器中获取有关可恢复语句的信息。

触发器还可以调用DBMS_RESUMABLE包来终止挂起的语句并修改恢复超时值。在下面的例子中,默认系统超时时间是通过创建一个系统层面的 AFTER SUSPEND触发器调用DBMS_RESUMABLE将超时时间设置为3小时:

SQL> CREATE OR REPLACE TRIGGER resumable_default_timeout
  2  AFTER SUSPEND
  3  ON DATABASE
  4  BEGIN
  5  DBMS_RESUMABLE.SET_TIMEOUT(10800);
  6  END;
  7  /

Trigger created.

可恢复的空间分配示例:注册一个AFTER SUSPEND触发器
一个示例说明了如何在挂起触发器后创建一个系统范围内的系统,并在数据库级别将其注册到SYS用户下。

当一个可恢复的语句在任何会话中被挂起时,这个触发器可以有两种效果:
.如果一个undo段已经达到了它的空间限制,那么一条消息将被发送给DBA,语句将被终止。

.如果出现其他可恢复的错误,则超时时间重置为8小时。

下面是这个例子的语句:

SQL> CREATE OR REPLACE NONEDITIONABLE TRIGGER resumable_default
  2  AFTER SUSPEND
  3  ON DATABASE
  4  DECLARE
  5  /* declare transaction in this trigger is autonomous */
  6  /* this is not required because transactions within a trigger
  7  are always autonomous */
  8  PRAGMA AUTONOMOUS_TRANSACTION;
  9  cur_sid NUMBER;
 10  cur_inst NUMBER;
 11  errno NUMBER;
 12  err_type VARCHAR2(2000);
 13  object_owner VARCHAR2(2000);
 14  object_type VARCHAR2(2000);
 15  table_space_name VARCHAR2(2000);
 16  object_name VARCHAR2(2000);
 17  sub_object_name VARCHAR2(2000);
 18  error_txt VARCHAR2(2000);
 19  msg_body VARCHAR2(2000);
 20  ret_value BOOLEAN;
 21  mail_conn UTL_SMTP.CONNECTION;
 22  BEGIN
 23  -- Get session ID
 24  SELECT DISTINCT(SID) INTO cur_SID FROM V$MYSTAT;
 25  -- Get instance number
 26  cur_inst := userenv('instance');
 27  -- Get space error information
 28  ret_value :=
 29  DBMS_RESUMABLE.SPACE_ERROR_INFO(err_type,object_type,object_owner,
 30  table_space_name,object_name, sub_object_name);
 31  /*
 32  -- If the error is related to undo segments, log error, send email
 33  -- to DBA, and abort the statement. Otherwise, set timeout to 8 hours.
 34  --
 35  -- sys.rbs_error is a table which is to be
 36  -- created by a DBA manually and defined as
 37  -- (sql_text VARCHAR2(1000), error_msg VARCHAR2(4000),
 38  -- suspend_time DATE)
 39  */
 40  IF OBJECT_TYPE = 'UNDO SEGMENT' THEN
 41  /* LOG ERROR */
 42  INSERT INTO sys.rbs_error (
 43  SELECT SQL_TEXT, ERROR_MSG, SUSPEND_TIME
 44  FROM DBA_RESUMABLE
 45  WHERE SESSION_ID = cur_sid AND INSTANCE_ID = cur_inst
 46  );
 47  SELECT ERROR_MSG INTO error_txt FROM DBA_RESUMABLE
 48  WHERE SESSION_ID = cur_sid and INSTANCE_ID = cur_inst;
 49  -- Send email to receipient through UTL_SMTP package
 50  msg_body:='Subject: Space Error Occurred Space limit reached for undo segment ' || object_name || 'on ' || TO_CHAR (SYSDATE, 'Month dd, YYYY, HH:MIam') ||'. Error message was ' || error_txt;
 51  mail_conn := UTL_SMTP.OPEN_CONNECTION('localhost', 25);
 52  UTL_SMTP.HELO(mail_conn, 'localhost');
 53  UTL_SMTP.MAIL(mail_conn, 'sender@localhost');
 54  UTL_SMTP.RCPT(mail_conn, 'recipient@localhost');
 55  UTL_SMTP.DATA(mail_conn, msg_body);
 56  UTL_SMTP.QUIT(mail_conn);
 57  -- Abort the statement
 58  DBMS_RESUMABLE.ABORT(cur_sid);
 59  ELSE
 60  -- Set timeout to 8 hours
 61  DBMS_RESUMABLE.SET_TIMEOUT(28800);
 62  END IF;
 63  /* commit autonomous transaction */
 64  COMMIT;
 65  END;
 66  /

Trigger created.

Oracle 18c 管理临时undo段

管理临时undo段
默认情况下,临时表的undo记录存储在undo表空间中,并在重做中记录,这与管理持久表的undo方式相同。但是,可以使用TEMP_UNDO_ENABLED 初始化参数来区分临时表的undo和持久表的undo。当此参数设置为TRUE时,对临时表的undo称为临时undo。

关于管理临时undo的概述
临时undo记录存储在数据库的临时表空间中,因此不会被记录在重做日志中。当启用临时undo时,临时表空间使用的一些段存储临时undo,这些 段称为临时undo段。

当启用临时undo时,可能需要增加临时表空间的大小来处理undo记录。

启用临时undo有以下好处:
.临时undo减少了存储在undo表空间中的undo量。undo表空间中较少的undo可以使undo记录的undo保留期需求更符合实际。

.临时undo减少了重做日志的大小。性能得到了提高,因为写入重做日志的数据更少,解析重做日志记录的组件(如LogMiner)性能更好,因为 需要解析的重做数据更少。

.临时undo使用Oracle Active data Guard选项对物理备用数据库中的临时表启用数据操作语言(DML)操作。但是,必须在主数据库上发出创建 临时表的数据定义语言(data definition language, DDL)操作。

可以为特定会话或整个系统启用临时undo。当使用ALTER session语句为会话启用临时undo时,会话将创建临时undo,而不会影响其他会话。当 您使用ALTER system语句为系统启用临时undo时,所有现有会话和新会话都会创建临时undo。

当会话第一次使用临时对象时,初始化参数TEMP_UNDO_ENABLED的当前值将用于会话的其余部分。因此,如果对会话启用了临时undo功能,并且 会话使用了临时对象,则不能对该会话禁用临时undo功能。类似地,如果对某个会话禁用了临时undo,而会话使用了临时对象,则不能对该会话 启用临时undo。

默认情况下,使用Oracle Active Data Guard选项为物理备用数据库启用临时undo。由于默认设置,TEMP_UNDO_ENABLED初始化参数对具有 Active Data Guard选项的物理备用数据库没有影响。

只有当数据库的兼容性级别为12.0.0或更高时,才能启用临时undo。

启用和禁用临时undo
可以为会话或系统启用或禁用临时undo。为此,需要设置初始化参数TEMP_UNDO_ENABLED。

启用或禁用临时undo:
1.在SQL*Plus中,连接到数据库。如果您正在启用或禁用会话的临时撤销,则在SQL*Plus中启动会话。

如果您正在启用或禁用系统的临时undo,那么在SQL*Plus中以具有ALTER system系统特权的管理用户身份进行连接。

[oracle@18c1 ~]$ sqlplus / as sysdba

SQL*Plus: Release 18.0.0.0.0 - Production on Fri Jun 5 17:25:10 2026
Version 18.3.0.0.0

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


Connected to:
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Version 18.3.0.0.0

2.设置TEMP_UNDO_ENABLED初始化参数:
.要启用会话的临时undo,运行以下SQL语句:

SQL> ALTER SESSION SET TEMP_UNDO_ENABLED = TRUE;

Session altered.

.要禁用会话的临时undo,请运行以下SQL语句:

SQL> ALTER SESSION SET TEMP_UNDO_ENABLED = FALSE;

Session altered.

.要为系统启用临时undo,请运行以下SQL语句:

SQL> ALTER SYSTEM SET TEMP_UNDO_ENABLED = TRUE;

System altered.

在为系统启用临时undo后,会话可以使用ALTER session语句禁用临时undo。

.要禁用系统的临时undo,请运行以下SQL语句:

SQL> ALTER SYSTEM SET TEMP_UNDO_ENABLED = FALSE;

System altered.

在为系统禁用临时undo后,会话可以使用ALTER session语句启用临时undo。

还可以通过在服务器参数文件或文本初始化参数文件中将TEMP_UNDO_ENABLED设置为TRUE来启用系统的临时undo。在这种情况下,所有的新会话 都会创建临时undo,除非通过ALTER system语句对系统禁用了临时undo,或者通过ALTER session语句对会话禁用了临时undo。

Oracle 18c 使用影子表空间来管理丢失写保护

使用影子表空间来管理丢失写保护

当I/O子系统确认块写入已完成,但在持久存储中没有发生写入时,就会发生数据块丢失写入。影子丢失写保护可以防止丢失写。
.关于影子丢失写保护
当I/O子系统确认块写入的完成,即使没有发生写入,或者当块的前一个镜像覆盖了当前的镜像时,就会发生数据块丢失写. 影子丢失写保护可以防止表空间或单个数据文件的丢失写。

.为影子丢失写保护创建影子表空间
为了给影子丢失写保护创建一个影子表空间,在执行create big file tablespace语句时使用lost write protection子句。

.对数据库启用影子丢失写保护
为了对一个多租户容器数据库(CDB)或一个非CDB启用影子丢人写保护,可以执行带有enable lost write protection子句的alter database语句。为了对一个PDB启用影子丢失写失保护,可以执行带有enable lost write protection子句的alter pluggable database语句。

.对表空间和数据文件启用影子丢失写保护
可以对表空间和数据文件启用影子丢失写保护

.对数据库禁用影子丢失写保护
为了对CDB或非CDB数据库禁用影子丢失写保护,执行带有disable lost write protection子句的alter database语句。为了对一个pdb禁用丢失写保护,执行带有disable lost write protection子句的alter pluggable database语句。

.删除或暂停影子丢失写保护
可以对表空间或数据文件删除或暂停影子丢失写保护

.删除影子表空间
可以执行drop tablespace语句来删除影子表空间。如果使用带有including contents子句的drop tablespace语句,那么影子表空间连同它的内容会一起被删除。如果使用不带including contents子句的drop tablespace语句,那么在删除影子表空间之前,影子表空间的内容在存在其它影子表空间且有足够的可用空间时会被移动到其它的影子表空间中。

关于影子丢失写保护
当I/O子系统确认块写入的完成,即使没有发生写入,或者当块的前一个镜像覆盖了当前的镜像时,就会发生数据块丢失写操作。影子丢失写保护可以防止表空间或数据文件发生丢失写。

影子丢失写保护对于丢失写提供了一种快速检测和立即响应的方法。使用影子丢失写保护可以最小化数据丢失和请求修复数据库所需要的时间。

为了使用影子丢失写保护,你必须对数据库启用并创建一个或多个影子表空间。一个影子表空间是一种特殊目的的大文件表空间它只包含跟踪数据文件的系统改变号(SCNs)。可以通过使用带有lost write protection子句的create tablespace语句来创建一个影子表空间。

当一个被跟踪的数据块从磁盘被读取时,影子丢失写保护通过比较在影子表空间中数据块的SCN与将被读取的数据块最近写入的SCN来检测是否发生了丢失写。如果影子条目的SCN大于被读数据块的SCN,那么发生了丢失写。当检测到丢失写时会返回一个错误。

未检测到的丢失写可能会造成数据损坏因为不正确的数据可能被用于其它的DML事务。影子丢失写保护在使用之前检测到丢失写,以防止数据损坏。可以对特定的表空间和数据文件启用影子丢失写保护。因此,可以对你最重要的数据启用它。你不必使用它来跟踪你的所有数据。

此外,影子表空间也是灵活的。您可以将一个影子表空间替换为另一个影子表空间,以更改其配置或位置。

当影子丢失写保护被启用后,可以对正常的DML操作和SQL*Loader常规路径加载和直接路径加载启用。也可以对RMAN备份启用。RMAN备份检查正在读取的块是否丢失写,如果找到这样的块,会引发错误。

在对表空间或数据文件启用影子丢失写保护之后,如果你想停止收集新的丢失写保护信息并检测丢失写可以暂停它。当影子丢失写保护被暂停之后,跟踪数据会被保存在影子表空间中,并且可以重新启用影子丢失写保护。如果对数据文件或表空间删除影子丢失写保护,那么它的跟踪数据会被删除并且不能重新使用。

可以通过执行带有lost write protection子句的alter tablespace语句来对表空间启用影子丢失写保护,执行带有lost write protection子句的alter database data_file_name语句来对数据文件启用影子丢失写保护。当对表空间启用影子丢失写保护后,表空间的所有当前和以后的数据文件都会启用影子丢失写保护。

Oracle数据库会自动对一个特定的影子表空间指派一个跟踪数据文件。你不能指定那个影子表空间使用某个特定的数据文件。影子表空间中的空间量应该至少为启用影子丢失写保护的数据文件所使用的空间的2%。

注意:
如果增加跟踪数据文件的大小,那么影子丢失写保护将试图重置影子表空间中的跟踪数据。如果没有足够的空间来跟踪所有数据,那么影子丢失写保护会向日志文件插入一条告警信息并使用它所能使用的影子空间来跟踪数据。

数据库闪回会造成任何影子丢失写保护数据被删除。在闪回之后,影子丢失写保护在重新填充时跟踪数据,并在块更新时对影子跟踪数据进行更新。

影子丢失写保护与使用DB_LOST_WRITE_PROTECT初始化参数和备用数据库配置的丢失写保护无关。

为影子丢失写保护创建影子表空间
可以使用带有lost write protection子句的create bigfile tablespace语句来为影子丢失写保护创建一个影子表空间。

一个影子表空间可以被任何启用影子丢失写保护的表空间或数据文件所使用。影子表空间的空间量至少是那些启用影子丢失写保护的数据文件大小的2%.

为了创建影子表空间,数据库的兼容级别必须至少为18.0.0或更高版本。

例如创建一个名为shadow_lwp1的影子表空间供影子丢失写保护使用

SQL> CREATE BIGFILE TABLESPACE shadow_lwp1 DATAFILE 'shadow_lwp1.df' SIZE 10M LOST WRITE PROTECTION;

Tablespace created.

对数据库启用影子丢失写保护
为了对一个CDB或非CDB启用影子丢失写保护,执行带有enable lost write protection子句的alter database语句。为了对pdb启用影子丢失写保护执行带有enable lost write protection子句的alter pluggable database语句。

在对单个表空间和数据文件启用影子丢失写保护之前,你必须至少创建一个影子表空间,并且必须对包含它的数据库启用影子丢失写保护。在执行这些配置后,可以通过执行alter tablespace语句来对表空间启用影子丢失写保护,并且可以通过执行alter database语句来为数据文件启用影子丢失写保护。

注意:
对数据库启用影子丢失写保护,那么数据库的兼容级别至少为18.0.0或更高版本,并且至少存在一个影子表空间。

对CDB root启用或禁用影子丢失写保护不影响PDBs的影子丢失写保护。因此即使对CDB root禁用了影子丢失写保护也还是能对PDB启用影子丢失写保护。

当对数据库启用影子丢失写保护时,会自动指派一个影子表空间供其使用。

对数据库启用影子丢失写保护操作如下:
1.通过SQL*Plus,使用有要求的权限的用户进行登录:
.对于非CDB或CDB root使用有alter database系统权限的用户进行登录。

.对于应用程序root,PDB或应用程序PDB,使用有alter pluggable database系统权限的用户进行登录。

2.执行以下操作:
.对于非CDB或CDB root,执行带有enable lost write protection子句的alter database语句。

.对于应用程序root,PDB或应用程序PDB,执行带有enable lost write protection子句的alter pluggable database语句。

对非CDB或CDB root启用影子丢失写保护

SQL> alter database enable lost write protection;

Database altered.

对PDB启用影子丢失写保护

SQL> alter pluggable database enable lost write protection;
alter pluggable database enable lost write protection
*
ERROR at line 1:
ORA-65491: A lost write bigfile tablespace must exist before attempting to
enable lost write


SQL> create bigfile tablespace shadow_pdb datafile 'shadow_pdb.dbf' size 10M lost write protection;

Tablespace created.

SQL> alter pluggable database enable lost write protection;

Pluggable database altered.

对表空间和数据文件启用影子丢失写保护
为了对表空间启用影子丢失写保护,执行带有enable lost write protection子句的alter tablespace语句。为了对数据文件启用影子丢失写保护执行带有enable lost write protection子句的alter database data_file_name语句。当对一个表空间启用了影子丢失写保护,那么就是对表空间的所有数据文件启用了影子丢失写保护,并且对于向表空间增加的任何数据文件也会启用影子丢失写保护。

注意:
.为了对一个表空间或数据文件启用影子丢失写保护那么数据库中必须至少存在一个影子表空间。
.当对一个表空间或数据文件启用影子丢失写保护,那么这个影子表空间会自动被分配给它。

为了对一个表空间或数据文件启用影子丢失写保护必须满足以下条件:
1.在SQL*Plus中,使用有以下权限的用户来连接数据库:
.如果计划对一个表空间启用影子丢失写保护,那么连接用户必须有alter tablespace权限。

.如果计划对非CDB或CDB root中的数据文件启用影子丢失写保护,那么连接用户必须有alter database权限。

.如果计划对一个应用程序root,PDB或应用程序PDB中的数据文件启用影子丢失写保护,那么连接用户必须有alter pluggable database权限。

2.执行以下操作来启用影子丢失写保护:
.为了对一个表空间启用影子丢失写保护,执行带有enable lost write protection子句的alter tablespace语句。

.为了对非CDB或CDB root中的数据文件启用影子丢失写保护,执行带有enable lost write protection子句的alter database data_file_name
语句。

.为了对一个应用程序root,PDB或应用程序PDB中的数据文件启用影子丢失写保护,执行带有enable lost write protection子句的alter pluggable database datafile data_file_name语句。

创建一个test表空间并启用影子丢失写保护:

SQL> create tablespace test datafile 'test01.dbf' size 10M;

Tablespace created.


SQL> alter tablespace test enable lost write protection;

Tablespace altered.

对非CDB或CDB root中的数据文件启用影子丢失写保护

SQL> create tablespace test1 datafile 'test1_01.dbf' size 10M;

Tablespace created.

SQL> alter tablespace test1 add datafile 'test1_02.dbf' size 10M;

Tablespace altered.

SQL> alter database datafile 'test1_01.dbf' enable lost write protection;

Database altered.

对一个应用程序root,PDB或应用程序PDB中的数据文件启用影子丢失写保护

SQL> alter session set container=hypdb;

Session altered.

SQL> create tablespace cs datafile 'cs01.dbf' size 10M;

Tablespace created.

SQL> alter pluggable database datafile 'cs01.dbf' enable lost write protection;

Pluggable database altered.

对数据库禁用影子丢失写保护
为了对CDB或非CDB禁用影子丢失写保护,执行带有disable lost write protection子句的alter database语句。为了对PDB禁用影子丢失写保护,执行带有disable lost write protection子句的alter pluggable database语句。

当你对一个数据库禁用影子丢失写保护后,不是这个数据库中的表空间或数据文件可以被影子丢失写保护。

注意:
.禁用影子丢失写保护不会删除现有影子表空间中的数据,但表空间中的数据不再被更新或被检查。如果想删除影子表空间中的数据,那么可以使用带有including contents子句的drop tablespace语句。

.对CDB root启用或禁用影子丢失写保护不会影响PDBs的影子丢失写保护。

为了对一个数据库禁用影子丢失写保护必须满足以下条件:
1.在SQL*Plus中,使用有以下权限的用户来连接数据库:
.在非CDB或CDB root中,那么连接用户必须有alter tablespace权限。

.在应用程序root,PDB或应用程序PDB中,那么连接用户必须有alter pluggable database权限。

2.执行以下操作来启用影子丢失写保护:
.对非CDB或CDB root,执行带有disable lost write protection子句的alter database语句。

.对应用程序root,PDB或应用程序PDB,执行带有disable lost write protection子句的alter pluggable database语句。

对非CDB或CDB root禁用影子丢失写保护

SQL> alter session set container=cdb$root;

Session altered.


SQL> alter database disable lost write protection;

Database altered.

对PDB禁用影子丢失写保护

SQL> alter session set container=hypdb;

Session altered.

SQL> alter pluggable database disable lost write protection;

Pluggable database altered.

删除或暂停影子丢失写保护
可以对表空间或数据文件删了或暂停影子丢失写保护。

当表空间或数据文件不再需要影子丢失写保护,可以选对以下操作:
.可以删除影子丢失写保护。这个操作会从影子表空间中删除表空间或数据文件的跟踪信息。这个选项也会停止对表空间或数据文件收集新的写丢失信息并且对他们的新丢失写停止检查。

.也可以暂停影子丢失写保护。停止对表空间或数据文件收集新的写丢失信息并且对他们的新丢失写停止检查。然而旧的丢失写信息仍然保留在影子表空间中。如果对表空间或数据文件重新启用影子丢失写保护,那么它们可以使用旧的丢失写信息。

当对表空间删除或暂停影子丢失写保护后,会删除影子丢失写保护或对表空间中的所有数据文件暂停影子丢失写保护。

为了对一个表空间或数据文件删除或暂停影子丢失写保护必须满足以下条件:
1.在SQL*Plus中,使用有以下权限的用户来连接数据库:
.如果计划对一个表空间删了或禁用影子丢失写保护,那么连接用户必须有alter tablespace权限。

.如果计划对非CDB或CDB root中的数据文件删除或禁用影子丢失写保护,那么连接用户必须有alter database权限。

.如果计划对一个应用程序root,PDB或应用程序PDB中的数据文件删除或禁用影子丢失写保护,那么连接用户必须有alter pluggable database权限。

2.执行以下操作来启用影子丢失写保护:
.为了对一个表空间删除或禁用影子丢失写保护,执行带有enable lost write protection或suspend lost write protection子句的alter tablespace语句。

.为了对非CDB或CDB root中的数据文件删除或禁用影子丢失写保护,执行带有enable lost write protection或suspend lost write protection 子句的alter database data_file_name语句。

.为了对一个应用程序root,PDB或应用程序PDB中的数据文件删除或禁用影子丢失写保护,执行带有enable lost write protection或suspend lost write protection子句的alter pluggable database datafile data_file_name语句。

删了表空间test的影子丢失写保护

SQL> alter session set container=cdb$root;

Session altered.

SQL> alter tablespace test remove lost write protection;

Tablespace altered.

暂停对数据文件test1_01.dbf的影子丢失写保护

SQL> alter database datafile 'test1_01.dbf' suspend lost write protection;

Database altered.

对PDB中的数据文件cs01.dbf暂停影子丢失写保护

SQL> alter session set container=hypdb;

Session altered.

SQL> alter pluggable database datafile 'cs01.dbf' suspend lost write protection;

Pluggable database altered.

删除影子表空间
可以执行drop tablespace语句来删除影子表空间。如果执行带有including contents子句的drop tablespace语句,那么在删除影子表空间的同时也会删除它的内容和数据文件。如果执行没带inclding contents子句的drop tablespace语句,那么在删除影子表空间之前,如果存在其它的影子表空间且有足够空间,它的内容会被移到另一个影子表空间中。

SQL> drop tablespace shadow_pdb including contents;

Tablespace dropped.