12新特性:只读分区

除了只读表以外,12c中引入了只读分区特性,每个分区或子分区可以独立的设置成只读或者读写,这样对于那些需要对指定分区数据的访问权限做控制的情况带来了方便。如果这个分区或子分区被设置成了只读模式,那么任何对这个分区或子分区的数据进行修改的操作都会报错,这样对这些数据进行了很好的保护。

只读分区:

  • 只读属性确保了数据的不变
  • 数据的不变并不会阻止表的DDL操作,比如新增和修改列
  • 表和分区或子分区都可以被设成只读

只读对象与只读表空间:

  • 只读表空间保护物理文件不被修改
    允许那些不接触存储的DDL操作,比如ALTER TABLE SET UNUSED,DROP TABLE
    不保证数据的不变
  • 只读对象保护数据不被修改
    数据的不变
    不阻止对存储的变化操作,比如ALTER TABLE MOVE COMPRESS,ALTER TABLE MERGE PARTITIONS

只读分区

drop table orders purge;

create table orders(order_id number,order_date date) read write
PARTITION BY RANGE(order_date)
( partition q1_2015 values less than (to_date('2014-10-01','yyyy-mm-dd')) READ ONLY,
 partition q2_2015 values less than (to_date('2015-01-01','yyyy-mm-dd')) READ ONLY,
 partition q3_2015 values less than (to_date('2015-04-01','yyyy-mm-dd')),
 partition q4_2015 values less than (to_date('2015-07-01','yyyy-mm-dd'))
);

# 查看user_tab_partitions视图
set linesize 300
col table_name for a30
col partition_name for a30
col read_only for a30
select table_name,partition_name,read_only from user_tab_partitions where table_name='ORDERS';

TABLE_NAME                     PARTITION_NAME                 READ_ONLY
------------------------------ ------------------------------ ------------------------------
ORDERS                         Q1_2015                        YES
ORDERS                         Q2_2015                        YES
ORDERS                         Q3_2015                        NO
ORDERS                         Q4_2015                        NO

这里orders表默认是读写属性,但是因为q1_2015和q2_2015两个分区指明了是只读,所以无法进行数据的修改,而其他两个分区则为可读写。

xb@PDB12C> insert into orders values(1,'2014-09-01');
insert into orders values(1,'2014-09-01')
*
ERROR at line 1:
ORA-14466: Data in a read-only partition or subpartition cannot be modified.


xb@PDB12C> insert into orders values(1,'2015-06-01');

1 row created.

xb@PDB12C> rollback;

Rollback complete.

同样也可以将表默认设置成只读模式,部分分区设成读写模式。

drop table orders purge;

create table orders(order_id number,order_date date) read only
PARTITION BY RANGE(order_date)
( partition q1_2015 values less than (to_date('2014-10-01','yyyy-mm-dd')) READ write,
 partition q2_2015 values less than (to_date('2015-01-01','yyyy-mm-dd')) ,
 partition q3_2015 values less than (to_date('2015-04-01','yyyy-mm-dd')),
 partition q4_2015 values less than (to_date('2015-07-01','yyyy-mm-dd'))
);

set linesize 300
col table_name for a30
col partition_name for a30
col read_only for a30
select table_name,partition_name,read_only from user_tab_partitions where table_name='ORDERS';

TABLE_NAME                     PARTITION_NAME                 READ_ONLY
------------------------------ ------------------------------ ------------------------------
ORDERS                         Q1_2015                        NO
ORDERS                         Q2_2015                        YES
ORDERS                         Q3_2015                        YES
ORDERS                         Q4_2015                        YES

只读子分区

drop table orders purge;

create table orders(order_id number,order_date date) read write
PARTITION BY list(order_id) 
subpartition by range(order_date)(
partition q1 values(1) read only
( subpartition q1_2014 values less than (to_date('2014-10-01','yyyy-mm-dd')),
 subpartition q1_2015 values less than (to_date('2015-01-01','yyyy-mm-dd')) 
),
partition q2 values(2)
( subpartition q2_2014 values less than (to_date('2014-10-01','yyyy-mm-dd')) read only,
 subpartition q2_2015 values less than (to_date('2015-01-01','yyyy-mm-dd')) 
)
);

这里注意到,对于表来说默认是读写,但对于q1分区默认却是只读,所以q1下的两个子分区都是只读状态,而q2分区默认是读写,q2_2014子分区是只读,另一个也是可读写,通过这个例子说明了在表、分区、子分区三个级别都可以独立的设置读写或只读属性。

xb@PDB12C> select partition_name, subpartition_name, read_only from user_tab_subpartitions where table_name ='ORDERS';

PARTITION_NAME                 SUBPARTITION_NAME              READ_ONLY
------------------------------ ------------------------------ ------------------------------
Q1                             Q1_2014                        YES
Q1                             Q1_2015                        YES
Q2                             Q2_2014                        YES
Q2                             Q2_2015                        NO

分区或子分区的读写状态也是可以变更的

xb@PDB12C> alter table orders modify partition q1 read write;

Table altered.

xb@PDB12C> alter table orders modify subpartition q1_2014 read only;

Table altered.

xb@PDB12C> select partition_name, subpartition_name, read_only from user_tab_subpartitions where table_name ='ORDERS';

PARTITION_NAME                 SUBPARTITION_NAME              READ_ONLY
------------------------------ ------------------------------ ------------------------------
Q1                             Q1_2014                        YES
Q1                             Q1_2015                        NO
Q2                             Q2_2014                        YES
Q2                             Q2_2015                        NO

而状态为只读的子分区也是无法修改数据的

xb@PDB12C> insert into orders values(1,'2014-06-01');
insert into orders values(1,'2014-06-01')
*
ERROR at line 1:
ORA-14466: Data in a read-only partition or subpartition cannot be modified.


xb@PDB12C> insert into orders values(1,'2014-11-01');

1 row created.

xb@PDB12C> rollback;

Rollback complete.