Oracle Read-only Tablespace(只读表空间)

[b]一,只读表空间与数据的备份/恢复[/b]

表空间设置成只读之后,只需要执行一次备份操作即可,在后续备份时不再需要考虑这些表空间的备份。原因很容易理解,这些表空间中的数据已经不再改变,存储在表空间中的数据状态始终保持在表空间设置为Read-Only那一刻,Oracle也不需要对它们进行额外的恢复工作,比如应用归档。

我们创建两个表空间,一个是只读(Read-Only)的,一个是常规的(Read-Write),下面来比较这两个表空间数据文件的变化情况。

SQL> create tablespace readonly datafile '/u01/app/oracle/oradata/readonly01.dbf' size 10m;

Tablespace created.

SQL> create tablespace readwrite datafile '/u01/app/oracle/oradata/readwrite01.dbf' size 10m;

Tablespace created.

SQL> alter tablespace readonly read only;

Tablespace altered.

这样,我们就创建了两个表空间readonly和readwrite,并把表空间readonly的状态设置为只读。

SQL> select name,file#,checkpoint_change#,status,enabled from v$datafile where name like '%read%';

NAME FILE# CHECKPOINT_CHANGE# status enabled
--------------------------------------------- ---------- -------------
/u01/app/oracle/oradata/readonly01.dbf 6 4342263 ONLINE READ ONLY
/u01/app/oracle/oradata/readwrite01.dbf 7 4341997 ONLINE READ WRITE

我们先记录下当前状态下两个表空间数据文件的CHECKPOINT_CHANGE#号,这个号表示表空间数据文件在Oracle数据库运行时某个时间点的状态。CHECKPOINT_CHANGE#是Oracle里面的一个序号,用来标识一个先后顺序,通常用于保护数据块的完整性或者一致性的查询。当数据块做了修改,它的CHECKPOINT_CHANGE#值就会发生相应的改变。

SQL> alter system checkpoint;

System altered.

我们发出一个CHECKPOINT命令,这个命令实际上是将内存中的脏数据块写入到磁盘上的文件中,并更新文件头部信息,以保证数据块中数据的一致性。

SQL> select name,file#,checkpoint_change#,status,enabled from v$datafile where name like '%read%';

NAME FILE# CHECKPOINT_CHANGE# status enabled
--------------------------------------------- ---------- -------------
/u01/app/oracle/oradata/readonly01.dbf 6 4342263 ONLINE READ ONLY
/u01/app/oracle/oradata/readwrite01.dbf 7 4343696 ONLINE READ WRITE

我们看到,执行了CHECKPOINT命令之后,READWRITE表空间数据文件的checkpoint_change#号发生了变化,这说明这个表空间相比之前的状态,它的数据文件已经产生了变化。
尽管我们没有对这个表空间做任何操作,但不能保证Oracle不这样做(实际上,这里是表空间数据文件的文件头数据块产生了变化)。我们知道,只要数据文件的checkpoint_change#号发生了变化,Oracle就需要进行恢复;而这里,READONLY的checkpoint_change#号并没有变化,看起来就像静止在那里一样。
这就是说,如果此时Oracle数据库出现问题,比如DOWN掉了,在数据库重新OPEN时,READONLY表空间是不需要恢复的,因为它的状态依然保持在将它置于READ-ONLY那一刻,那一刻数据库是好的。
而READWRITE表空间就不同了,如果此时数据库DOWN掉了,它就需要进行恢复,因为这个表空间上的数据块状态是持续更新的,它需要通过联机日志(或者归档日志)将它恢复到最后Oracle数据库DOWN掉时的状态。

我们继续来看,现在将这两个表空间的状态改为离线。
SQL> alter tablespace readonly offline;

Tablespace altered.

SQL> alter tablespace readwrite offline;

Tablespace altered.

SQL> select name,file#,checkpoint_change#,status,enabled from v$datafile where name like '%read%';

NAME FILE# CHECKPOINT_CHANGE# status enabled
--------------------------------------------- ---------- -------------
/u01/app/oracle/oradata/readonly01.dbf 6 4342263 OFFLINE READ ONLY
/u01/app/oracle/oradata/readwrite01.dbf 7 4351566 OFFLINE READ WRITE

我们看到,READONLY表空间的checkpoint_change#号依然保持不变。

SQL> alter system checkpoint;

System altered.

SQL> select name,file#,checkpoint_change#,status,enabled from v$datafile where name like '%read%';

NAME FILE# CHECKPOINT_CHANGE# status enabled
--------------------------------------------- ---------- -------------
/u01/app/oracle/oradata/readonly01.dbf 6 4342263 OFFLINE READ ONLY
/u01/app/oracle/oradata/readwrite01.dbf 7 4351566 OFFLINE READ WRITE

当数据文件状态为离线时,不论之前它是只读还是读写表空间,它的状态都不再改变。

现在,我们把这两个表空间的状态重新改为在线。

SQL> alter tablespace readonly online;

Tablespace altered.

SQL> alter tablespace readwrite online;

Tablespace altered.

SQL> select name,file#,checkpoint_change#,status,enabled from v$datafile where name like '%read%';

NAME FILE# CHECKPOINT_CHANGE# status enabled
--------------------------------------------- ---------- -------------
/u01/app/oracle/oradata/readonly01.dbf 6 4342263 OFFLINE READ ONLY
/u01/app/oracle/oradata/readwrite01.dbf 7 4351660 OFFLINE READ WRITE

我们看到,READWRITE表空间的checkpoint_change#号再次改变了。实际上,在把READWRITE表空间的状态改为在线时,Oracle对它进行了恢复操作,使它的状态和数据库当前状态一致;而READONLY表空间依然静止不动地保持着它最初的状态,和数据库的变化毫无关系。
这样看来,在备份和恢复上,对只读表空间备份一次就够了;而对其他的读写表空间的备份,可能需要定期做全备份或者增量备份,同时还需要备份恢复时所需要的归档日志。这些备份集不但需要大量的磁盘空间,而且恢复时也可能会相当耗时。

[b]二,只读表空间可以防止数据被意外删除和修改[/b]

----创建一个jack表空间----
SQL> create tablespace jack datafile '/u01/app/oracle/oradata/jack01.dbf' size 500m;

Tablespace created.

SQL> show user;
USER is "JACK"

----创建一张表jack----
SQL> create table jack tablespace jack as select * from dba_objects;

Table created.

----将表空间状态设置为只读----
SQL> alter tablespace jack read only;

Tablespace altered.

----做一些修改数据的操作,无法进行DELETE操作----
SQL> delete from jack;
delete from jack
*
ERROR at line 1:
ORA-00372: file 6 cannot be modified at this time
ORA-01110: data file 6: '/u01/app/oracle/oradata/jack01.dbf'

----无法进行UPDATE操作----
SQL> update jack set object_id=object_id*10;
update jack set object_id=object_id*10
*
ERROR at line 1:
ORA-00372: file 6 cannot be modified at this time
ORA-01110: data file 6: '/u01/app/oracle/oradata/jack01.dbf'

----无法进行INSERT操作,也就是说,对于只读表空间上的数据,无法进行DML操作。----
SQL> insert into jack select * from dba_objects;
insert into jack select * from dba_objects
*
ERROR at line 1:
ORA-00372: file 6 cannot be modified at this time
ORA-01110: data file 6: '/u01/app/oracle/oradata/jack01.dbf'

----也无法进行TRUNCATE操作,说明在只读表空间上,对数据(说的是对象里面的数据)的所有操作都是不允许的,看起来数据还是比较安全的----
SQL> truncate table jack;
truncate table jack
*
ERROR at line 1:
ORA-00372: file 6 cannot be modified at this time
ORA-01110: data file 6: '/u01/app/oracle/oradata/jack01.dbf'

----当表空间处于只读的时候,我们可以对表进行其他的修改,给表增加字段----
SQL> alter table jack add new_col varchar2(10);

Table altered.

SQL> alter table jack modify object_name varchar2(2000);

Table altered.

----在这里我们可以看到新的字段NEW_COL已经增加,OBJECT_NAME的属性已经修改成VARCHAR2(2000)----

SQL> desc jack;
Name Null? Type
--------------------- -------- ----------------------------
OWNER VARCHAR2(30)
OBJECT_NAME VARCHAR2(2000)
SUBOBJECT_NAME VARCHAR2(30)
OBJECT_ID NUMBER
DATA_OBJECT_ID NUMBER
OBJECT_TYPE VARCHAR2(19)
CREATED DATE
LAST_DDL_TIME DATE
TIMESTAMP VARCHAR2(19)
STATUS VARCHAR2(7)
TEMPORARY VARCHAR2(1)
GENERATED VARCHAR2(1)
SECONDARY VARCHAR2(1)
NAMESPACE NUMBER
EDITION_NAME VARCHAR2(30)
NEW_COL VARCHAR2(10)

----无法删除字段----
SQL> alter table jack drop column new_col;
alter table jack drop column new_col
*
ERROR at line 1:
ORA-12985: tablespace 'JACK' is read only, cannot drop column

----可以删除索引和表----
SQL> alter tablespace jack read write;

Tablespace altered.

SQL> create index jack on jack(object_id);

Index created.

SQL> alter tablespace jack read only;

Tablespace altered.

SQL> drop index jack;

Index dropped.

SQL> create table persons(
PERSON_ID NUMBER(8) NOT NULL,
FIRST_NAME VARCHAR2(32) NOT NULL,
LAST_NAME VARCHAR2(32) NOT NULL
) tablespace jack;

Table created.

SQL> drop table persons;

Table dropped.

总结:

凡是要对表空间上的数据进行修改的操作都不允许。比如:
INSERT UPDATE DELETE TRUNCATE
实际上,只读表空间上的数据块连Oracle都不会修改(checkpoint_change#号从来都不会改变),这些修改数据的操作自然不被允许的。
那么,创建空表和给表增加字段或者修改字段的属性操作为什么就可以呢?因为此操作根本就不需要去触碰这个只读表空间,我们只要修改Oracle字典表中的信息就可以了(Oracle的对象属性是存储在数据字典中的,而字典表是存储在SYSTEM表空间上的),因此,这样的操作是被允许的。
同样的,删除一个字段,不仅仅要修改数据字典中表的相关信息,还涉及将该字段上的数据内容从表上抹掉,需要修改表空间上的数据块,因此,不被允许。

这样就清晰了:
凡是需要修改表空间数据块的操作,都不被允许。反之,则可以。

最后,删除这个表以及表上的索引是允许的,因为Oracle只需要从数据字典中将它的所有信息抹去就可以了。
### 回答1: 在 Oracle 数据库中,只读表空间无法进行更新操作,因此需要采用特殊的方式进行恢复。以下是在使用 RMAN 进行只读表空间恢复的步骤: 1. 在正常情况下,只读表空间无法进行备份。因此,我们需要在只读表空间变为可写状态之后进行备份。可以使用以下命令将只读表空间变为可写状态: ``` ALTER TABLESPACE tablespace_name READ WRITE; ``` 2. 确认只读表空间已经变为可写状态,并且进行备份。 3. 当只读表空间出现问题需要恢复时,需要先将只读表空间变为可写状态。可以使用以下命令将只读表空间变为可写状态: ``` ALTER TABLESPACE tablespace_name READ WRITE; ``` 4. 使用 RMAN 进行恢复操作。可以使用以下命令进行只读表空间恢复: ``` RMAN> RUN { SET NEWNAME FOR DATAFILE 'datafile_path' TO 'new_datafile_path'; RESTORE TABLESPACE tablespace_name; RECOVER TABLESPACE tablespace_name; } ``` 其中,`datafile_path` 是只读表空间的数据文件路径,`new_datafile_path` 是恢复后的数据文件路径。 5. 恢复完成后,将只读表空间变为只读状态。可以使用以下命令将只读表空间变为只读状态: ``` ALTER TABLESPACE tablespace_name READ ONLY; ``` 以上就是使用 RMAN 进行只读表空间恢复的步骤。需要注意的是,在进行只读表空间恢复前,必须将只读表空间变为可写状态,并进行备份。 ### 回答2: Oracle的RMAN(Recovery Manager)是一个备份和恢复工具,用于管理数据库的备份和恢复操作。在恢复只读表空间时,我们可以按照以下步骤进行操作: 1. 首先,使用RMAN备份只读表空间。我们可以使用备份命令将只读表空间备份到一个可用的位置,以便在恢复过程中将其还原回数据库。例如,可以使用类似如下的备份命令: RMAN> BACKUP TABLESPACE tablespacename; 2. 在确认备份已经完成后,我们可以开始恢复只读表空间。首先,将只读表空间离线,并清空表空间。可以使用以下SQL语句来执行此操作: SQL> ALTER TABLESPACE tablespacename OFFLINE IMMEDIATE; SQL> DROP TABLESPACE tablespacename INCLUDING CONTENTS AND DATAFILES; 3. 接下来,使用RMAN将备份的只读表空间还原到数据库。我们可以使用如下命令将备份的只读表空间还原到数据库中: RMAN> RESTORE TABLESPACE tablespacename; 4. 在还原完成后,将只读表空间重新设置为只读模式。使用以下SQL语句来执行此操作: SQL> ALTER TABLESPACE tablespacename READ ONLY; 通过以上步骤,我们可以使用RMAN备份和恢复工具来成功恢复只读表空间。需要注意的是,恢复只读表空间时需要进行足够的备份,以便能够还原到最近可用的状态,并确保在恢复过程中不会丢失任何数据。 ### 回答3: Oracle的RMAN(Recovery Manager)可以用于恢复只读表空间。以下是恢复只读表空间的步骤: 1. 首先,确定需要恢复的只读表空间的名称。可以通过查询数据库的v$tablespace视图来获取表空间的信息。 2. 在RMAN命令行界面中,连接到目标数据库。 3. 运行以下命令来将表空间置为可读写状态: ``` SQL 'ALTER TABLESPACE <tablespace_name> READ WRITE'; ``` 4. 运行以下命令来检测并修复表空间的结构问题: ``` RECOVER TABLESPACE <tablespace_name>; ``` 5. 运行以下命令来还原和恢复表空间中的数据文件: ``` RESTORE TABLESPACE <tablespace_name>; RECOVER TABLESPACE <tablespace_name>; ``` 6. 最后,将表空间设置为只读状态: ``` SQL 'ALTER TABLESPACE <tablespace_name> READ ONLY'; ``` 需要注意的是,在执行恢复操作之前,最好备份数据库以及相关的数据文件。此外,恢复只读表空间可能需要一定的时间,具体取决于表空间大小和系统配置。 总之,使用RMAN工具可以方便地恢复只读表空间,确保数据库的完整性和可用性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值