Oracle报告分区索引

Oracle报告分区索引
从关于索引的数据字典中可以收集到很多信息,它们包括以下内容:
.分区名称
.索引类型
.索引分区的状态(需要查询相应的视图)
.索引分区的大小

在下面的例子中,你只是希望得到employees_part表的索引名,分区名和状态的列表。因为此表上既有分区索引又有非分区索引。所以你用union操作把对两种索引的查询合并在一起。

SQL> select table_name,index_name,partition_name,p.status
  2  from user_ind_partitions p join user_indexes i using(index_name)
  3  where table_name='EMPLOYEES_PART'
  4  union
  5  select table_name,index_name,null,status
  6  from user_indexes
  7  where table_name='EMPLOYEES_PART'
  8  order by 2,3;

TABLE_NAME                     INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ------------------------------ ---------------------------------------- --------
EMPLOYEES_PART                 EMPLOYEES_PART_PK                                                       VALID
EMPLOYEES_PART                 EMPLOYEES_PART_UK1             MANAGER_100                              UNUSABLE
EMPLOYEES_PART                 EMPLOYEES_PART_UK1             MANAGER_200                              UNUSABLE
EMPLOYEES_PART                 EMPLOYEES_PART_UK1             MANAGER_300                              UNUSABLE
EMPLOYEES_PART                 EMPLOYEES_PART_UK1             MANAGER_400                              UNUSABLE
EMPLOYEES_PART                 EMPLOYEES_PART_UK1             MANAGER_500                              UNUSABLE
EMPLOYEES_PART                 EMPLOYEES_PART_UK1             MANAGER_600                              UNUSABLE
EMPLOYEES_PART                 EMPLOYEES_PART_UK1             MANAGER_700                              UNUSABLE
EMPLOYEES_PART                 EMPLOYEES_PART_UK1             MANAGER_800                              UNUSABLE
EMPLOYEES_PART                 EMPLOYEES_PART_UK1             MANAGER_900                              UNUSABLE
EMPLOYEES_PART                 EMPLOYEES_PART_UK1             MANAGER_MAX                              USABLE
EMPLOYEES_PART                 EMPLOYEES_PART_UK1                                                      N/A
EMPLOYEES_PART                 EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEES_PART                 EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEES_PART                 EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEES_PART                 EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEES_PART                 EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEES_PART                 EMPLOYEE_PART_LI               P1995                                    USABLE
EMPLOYEES_PART                 EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEES_PART                 EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEES_PART                 EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEES_PART                 EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEES_PART                 EMPLOYEE_PART_LI               P2000                                    USABLE
EMPLOYEES_PART                 EMPLOYEE_PART_LI               PMAX                                     USABLE
EMPLOYEES_PART                 EMPLOYEE_PART_LI                                                        N/A

25 rows selected.

请注意,在查询user_indexes视图时,分区索引对应的状态(status)列中显示N/A(表示不可用)。只有(基于索引分区的)最精细的数据字典视图的状态列才会被填入数据。也就是说,对于分区索引,user_ind_partitions视图的status列将被填充。如果你查询的最子分区索引,那么只有user_ind_subpartitions视图的status列将被填充,而user_indexes和user_ind_partitions视图的status列将是N/A。

接下来,需要执行一个查询,以确定表上所有索引分区的类型.

SQL> select table_name,index_name,partitioning_type,locality,alignment from user_part_indexes;

TABLE_NAME                     INDEX_NAME                     PARTITION LOCALI ALIGNMENT
------------------------------ ------------------------------ --------- ------ ------------
EMPLOYEES_JY                   EMPLOYEES_UK1                  RANGE     GLOBAL PREFIXED
EMPLOYEES_JY                   EMPLOYEES_JY_IH1               HASH      GLOBAL PREFIXED
EMPLOYEES_PART                 EMPLOYEE_PART_LI               RANGE     LOCAL  PREFIXED
EMPLOYEES_PART                 EMPLOYEES_PART_UK1             RANGE     GLOBAL PREFIXED

在查询段信息时,需要注意区分子分区索引。对于子分区索引,为了获得子分区的信息,大多数数据字典视图中都有一个子分区列。但这有一个例外,当需要从dba_segments等视图中获得段信息时,只有实际分区或表示实际段的子分区名才会在dba_segments中表示。换句话说,对于子分区索引,子分区名称将在dba_segments的partition_name列中出现。在下面的例子中,想要获得billing_fact表中大小超过8GB的索引子分区。你对user_ind_subpartitions执行了一个子查询,这表明dba_segments视图的partition_name列实际上代表了user_ind_subpartitions视图的subpartition_name列。

select segment_name,partition_name,round(bytes/1048576) meg
from dba_segments
where (segment_name,partition_name) in
(select index_name,subpartition_name from user_ind_subpartitions
where index_name in
(select index_name from user_indexes
where table_name='BILLING_FACT'))
and bytes>1048576*8192
order by 3 desc;

Oracle把索引分区设置为不可用后重建

把索引分区设置为不可用后重建
在数据仓库环境中装载大量数据时,由于索引的存在,批量dml操作的速度可能会非常慢。分区索引的关键好处之一是,可以在批量加载数据前,把索引的某些部分设置为unusable,然后在加载完成后,仅仅需要对那些受影响的部分索引分区进行重建。

从根本上说,先把索引标记为不可用,然后重建索引是相当简单的。例如:

SQL> alter table employees_part modify partition pmax unusable local indexes;

Table altered.
SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO'
  2  union
  3  select index_name,partition_name,status from user_ind_partitions where index_name in
  4  (select index_name from user_indexes where table_name='EMPLOYEES_PART')
  5  order by 1,2,3;

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEES_PART_PK                                                       VALID
EMPLOYEES_PART_UK1             MANAGER_100                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_200                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_300                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_400                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_500                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_600                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_700                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_800                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_900                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_MAX                              USABLE
EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEE_PART_LI               P1995                                    USABLE
EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEE_PART_LI               P2000                                    USABLE
EMPLOYEE_PART_LI               PMAX                                     UNUSABLE

23 rows selected.

然后,在批量加载操作完成之后,就可以执行以下命令,重建那些受批量加载操作影响的索引分区:

SQL> alter table employees_part modify partition pmax rebuild unusable local indexes;

Table altered.

SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO'
  2  union
  3  select index_name,partition_name,status from user_ind_partitions where index_name in
  4  (select index_name from user_indexes where table_name='EMPLOYEES_PART')
  5  order by 1,2,3;

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEES_PART_PK                                                       VALID
EMPLOYEES_PART_UK1             MANAGER_100                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_200                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_300                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_400                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_500                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_600                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_700                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_800                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_900                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_MAX                              USABLE
EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEE_PART_LI               P1995                                    USABLE
EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEE_PART_LI               P2000                                    USABLE
EMPLOYEE_PART_LI               PMAX                                     USABLE

23 rows selected.

使用此命令重建索引有一个明显的缺点:索引分区是顺序建立的,即一次重建一个索引分区。如果表上有许多索引,那么用这个命令会减缓重建过程,如果此操作是常规性处理任务的一部分,那么这种减缓会令人难以接受。一种缓解alter table … rebuild local indexes unusable命令的串行限制的方法是,并行重建每个受影响的分区。

实现并行重建索引操作有好几种方法。

Oracle重建全局分区索引和非分区索引

重建全局分区索引和非分区索引

对表进行任何一种分区级的操作,几乎都会使用所有全局分区索引或非分区索引无法使用。从本质上讲,索引始终必须重建。Oracle11g中的一个内置功能,允许把重建索引作为分区表操作的一部分来执行。使用分区级合并操作的例子,你可以看到,可以在alter table … merge命令中添加更新索引(update indexes)子句,这指示Oracle重建被分区级操作标记为不可用的任何索引。请看下面的例子:

SQL> alter table employees_part merge partitions p2001,pmax into partition pmax update indexes;

Table altered.

SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO'
  2  union
  3  select index_name,partition_name,status from user_ind_partitions where index_name in
  4  (select index_name from user_indexes where table_name='EMPLOYEES_PART')
  5  order by 1,2,3;

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEES_PART_PK                                                       VALID
EMPLOYEES_PART_UK1             MANAGER_100                              USABLE
EMPLOYEES_PART_UK1             MANAGER_200                              USABLE
EMPLOYEES_PART_UK1             MANAGER_300                              USABLE
EMPLOYEES_PART_UK1             MANAGER_400                              USABLE
EMPLOYEES_PART_UK1             MANAGER_500                              USABLE
EMPLOYEES_PART_UK1             MANAGER_600                              USABLE
EMPLOYEES_PART_UK1             MANAGER_700                              USABLE
EMPLOYEES_PART_UK1             MANAGER_800                              USABLE
EMPLOYEES_PART_UK1             MANAGER_900                              USABLE
EMPLOYEES_PART_UK1             MANAGER_MAX                              USABLE
EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEE_PART_LI               P1995                                    USABLE
EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEE_PART_LI               P2000                                    USABLE
EMPLOYEE_PART_LI               PMAX                                     USABLE

23 rows selected.

使用update indexes子句重建索引的一个关键优势是,在重建操作过程中索引仍然是在线和可用的。虽然上述例子非常简单,但使用update indexes子句的缺点之一是,由于在分区级别的操作中包装了索引重建操作,在如何重建索引方面,你失去了一定的灵活性。例如,如果你有多个索引需要重建。分别发出命令来重建每个索引的速度可能会更快。要达到这种效果,就可以同时并发地运行多个alter index … rebuild命令。虽然这种方法比较复杂,但哪怕只为了加快速度,这么做可能也是有必要的。

要重建非分区索引,只需要执行alter index … rebuild命令即可。

SQL> alter index employees_part_pk rebuild;

Index altered.

此外,对于每个索引,可以选择性地决定使用并行机制,如下面的例子所示:

SQL> alter index employees_part_pk rebuild parallel(degree 4);

Index altered.

SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO'
  2  union
  3  select index_name,partition_name,status from user_ind_partitions where index_name in
  4  (select index_name from user_indexes where table_name='EMPLOYEES_PART')
  5  order by 1,2,3;

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEES_PART_PK                                                       VALID
EMPLOYEES_PART_UK1             MANAGER_100                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_200                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_300                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_400                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_500                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_600                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_700                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_800                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_900                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_MAX                              UNUSABLE
EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEE_PART_LI               P1995                                    USABLE
EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEE_PART_LI               P2000                                    USABLE
EMPLOYEE_PART_LI               PMAX                                     USABLE

23 rows selected.

使用这种方法同样需要有足够的判断力和常识。如果需要一次性重建许多索引,同时又想使用并行机制,那么你必须注意到并发操作会有一个缺点。这需要根据具体的环境来作出决定。最初,最好用谨慎的态度开始。可以先慢慢提交少量的操作,以确保并发操作不造成IO或CPU瓶颈,也不造成临时表空间的瓶颈。如果并发操作没有造成这些瓶颈,那么就可以同时运行更多的重建命令。

重建非分区索引还有另一种选择,即简单地删除非分区不可用索引,并使用create index命令重新创建索引。

如果要重建全局分区索引,也有两种选择,既可以删除索引并使用create index命令作为一个整体重新创建索引,也可以逐个分区的重建全局分区索引。请看下面的例子:

SQL> alter index employees_part_uk1 rebuild partition manager_max;

Index altered.

SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO'
  2  union
  3  select index_name,partition_name,status from user_ind_partitions where index_name in
  4  (select index_name from user_indexes where table_name='EMPLOYEES_PART')
  5  order by 1,2,3;

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEES_PART_PK                                                       VALID
EMPLOYEES_PART_UK1             MANAGER_100                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_200                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_300                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_400                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_500                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_600                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_700                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_800                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_900                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_MAX                              USABLE
EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEE_PART_LI               P1995                                    USABLE
EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEE_PART_LI               P2000                                    USABLE
EMPLOYEE_PART_LI               PMAX                                     USABLE

23 rows selected.

你将需要对每个全局索引分区执行alter index … rebuild命令。

请注意不能把全局分区索引作为一个整体来重建。请看下面的例子:

SQL> alter index employees_part_uk1 rebuild;
alter index employees_part_uk1 rebuild
            *
ERROR at line 1:
ORA-14086: a partitioned index may not be rebuilt as a whole

正因为如此,当整个全局分区索引被标记为unusable时,删除它并使用create index命令重新创建索引,这样操作起来可能更为简单。

Oracle 维护分区表的索引

维护分区表的索引
虽然分区表和分区索引提供了许多好处,但在设计应用程序时就必须考虑到,创建分区表和分区索引对维护产生的影响。根据环境的情况和具体的应用程序设计和数据库设计,维护操作也会有所不同。对于你的具体应用程序,这包括应用程序的DML模式和被插入,更新和删除的数据量。索引的存在会造成DML操作速度减慢。在某些应用程序中,特别是在数据仓库领域,执行分区一级的操作有利于加快应用程序整体处理速度。分区级的操作可能会对索引产生重大影响,这取决于应用程序使用了什么类型的索引。

下面的例子展示了分区级的操作对不同类型索引的影响。每个例子使用一个测试表,其中包含员工数据。此表上有三个索引:一个非分区索引(employees_part_i1),一个本地分区索引(employees_part_li1)和一个全局分区索引(employees_parttest_gi1)。你会看到对表执行分区级别的操作对表内每个索引的实际影响。

注意:如果在分区表任何一个空的分区上执行下列操作,所有相关索引均不受影响。这对各种索引类型都是成立的,不管它们是本地分区,全局分区还是非分区的索引。

SQL> create table employees_part
  2  (
  3  employee_id number(6) not null,
  4  first_name varchar2(20),
  5  last_name varchar2(25) not null,
  6  email varchar2(25) not null,
  7  phone_numbr varchar2(20),
  8  hire_date date not null,
  9  job_id varchar2(10) not null,
 10  salary number(8,2),
 11  commission_pct number(2,2),
 12  manager_id number(6),
 13  department_id number(4),
 14  constraint employees_part_pk primary key(employee_id,hire_date)
 15  )
 16  partition by range(hire_date)
 17  (
 18  partition p1990 values less than(to_date('1991-01-01','yyyy-mm-dd')),
 19  partition p1991 values less than(to_date('1992-01-01','yyyy-mm-dd')),
 20  partition p1992 values less than(to_date('1993-01-01','yyyy-mm-dd')),
 21  partition p1993 values less than(to_date('1994-01-01','yyyy-mm-dd')),
 22  partition p1994 values less than(to_date('1995-01-01','yyyy-mm-dd')),
 23  partition p1995 values less than(to_date('1996-01-01','yyyy-mm-dd')),
 24  partition p1996 values less than(to_date('1997-01-01','yyyy-mm-dd')),
 25  partition p1997 values less than(to_date('1998-01-01','yyyy-mm-dd')),
 26  partition p1998 values less than(to_date('1999-01-01','yyyy-mm-dd')),
 27  partition p1999 values less than(to_date('2000-01-01','yyyy-mm-dd')),
 28  partition p2000 values less than(to_date('2001-01-01','yyyy-mm-dd')),
 29  partition pmax values less than(maxvalue)
 30  );

Table created.

SQL> create index employee_part_li on employees_part(hire_date) local;

Index created.

SQL> select partition_name,status from user_ind_partitions where index_name='EMPLOYEE_PART_LI';

PARTITION_NAME                                                                                                                   STATUS
-------------------------------------------------------------------------------------------------------------------------------- --------
P1990                                                                                                                            USABLE
P1991                                                                                                                            USABLE
P1992                                                                                                                            USABLE
P1993                                                                                                                            USABLE
P1994                                                                                                                            USABLE
P1995                                                                                                                            USABLE
P1996                                                                                                                            USABLE
P1997                                                                                                                            USABLE
P1998                                                                                                                            USABLE
P1999                                                                                                                            USABLE
P2000                                                                                                                            USABLE
PMAX                                                                                                                             USABLE

12 rows selected.

1 添加分区
往表中添加分区对表上现有的索引影响最小。事实上,无论你选择使用什么索引类型(本地分区,全局分区或非分区),在添加分区操作后,任何现存的索引分区都不会受到影响,也不需要特定的索引级别的操作。下面的例子向测试员工表中添加一个分区,用于保存2001年的历史数据:

SQL> alter table employees_part add partition p2001 values less than(to_date('2002-01-01','yyyy-mm-dd'));
alter table employees_part add partition p2001 values less than(to_date('2002-01-01','yyyy-mm-dd'))
                                         *
ERROR at line 1:
ORA-14074: partition bound must collate higher than that of the last partition


SQL> alter table employees_part drop partition pmax;

Table altered.

SQL> select partition_name,status from user_ind_partitions where index_name='EMPLOYEE_PART_LI';

PARTITION_NAME                                                                                                                   STATUS
-------------------------------------------------------------------------------------------------------------------------------- --------
P1990                                                                                                                            USABLE
P1991                                                                                                                            USABLE
P1992                                                                                                                            USABLE
P1993                                                                                                                            USABLE
P1994                                                                                                                            USABLE
P1995                                                                                                                            USABLE
P1996                                                                                                                            USABLE
P1997                                                                                                                            USABLE
P1998                                                                                                                            USABLE
P1999                                                                                                                            USABLE
P2000                                                                                                                            USABLE

11 rows selected.

SQL> alter table employees_part add partition p2001 values less than(to_date('2002-01-01','yyyy-mm-dd'));

Table altered.

添加分区后,可以运行以下查询来确实添加分区(add partition)操作对表上现有索引的影响:

SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO'
  2  union
  3  select index_name,partition_name,status from user_ind_partitions where index_name in
  4  (select index_name from user_indexes where table_name='EMPLOYEES_PART')
  5  order by 1,2,3;

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEES_PART_PK                                                       VALID
EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEE_PART_LI               P1995                                    USABLE
EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEE_PART_LI               P2000                                    USABLE
EMPLOYEE_PART_LI               P2001                                    USABLE

13 rows selected.

2 截断分区
截断分区是删除一个表分区内所有数据的最简单的方法。而且,对于创建了本地分区索引的表,截断表分区不影响底层的索引分区,其中包括被截断的分区。然而,如果你的表上有非分区索引或者全局分区索引,截断分区就会使得Oracle无法知道哪些索引条目受到了截断操作的影响。因此,Oracle别无选择,只能简单地把整个索引标记为unusable。例如:

SQL> create index employees_part_uk1 on employees_part(manager_id)
  2  global
  3  partition by range(manager_id)
  4  (
  5  partition manager_100 values less than(100),
  6  partition manager_200 values less than(200),
  7  partition manager_300 values less than(300),
  8  partition manager_400 values less than(400),
  9  partition manager_500 values less than(500),
 10  partition manager_600 values less than(600),
 11  partition manager_700 values less than(700),
 12  partition manager_800 values less than(800),
 13  partition manager_900 values less than(900),
 14  partition manager_max values less than(maxvalue)
 15  );

Index created.

SQL> alter table employees_part truncate partition p1995;

Table truncated.

SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO'
  2  union
  3  select index_name,partition_name,status from user_ind_partitions where index_name in
  4  (select index_name from user_indexes where table_name='EMPLOYEES_PART')
  5  order by 1,2,3;

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEES_PART_PK                                                       VALID
EMPLOYEES_PART_UK1             MANAGER_100                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_200                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_300                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_400                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_500                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_600                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_700                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_800                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_900                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_MAX                              UNUSABLE
EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEE_PART_LI               P1995                                    USABLE
EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEE_PART_LI               P2000                                    USABLE
EMPLOYEE_PART_LI               P2001                                    USABLE

23 rows selected.

3 移动分区
移动分区有各种原因。你可能需要将一些表或分区移动到不同的表空间,也可能会决定压缩某个分区的数据,或者可能因为大量的更新操作已经导致了行迁移而需要重组表的分区。

执行移动分区操作时,你会再次看到本地分区索引受到的影响是最小的。本地分区索引的分区级移动操作与截断操作的一个关键的区别在于,被移动分区的索引已被标记为unusable。因为移动分区中的每一行后,现在每一行的rowid值都与先前的不同,所以Oracle需要这么做,因此该索引分区的条目现在是无效的,因为它们现在包含过时的rowid项。被移动的索引分区需要重建,以反映新的rowid值。

与截断分区的例子一样,Oracle不了解该表上的全局分区和非分区索引的表分区边界,因此需要把整个索引标志为unusable,且整个索引都需要重建安。对于本地分区索引,只需要重建受移动的表分区影响的索引分区。

在下面的例子中,需要把较旧的1995年的员工数据移动到它自己的表空间,这可能是为了能把它设置成只读:

SQL> alter table employees_part move partition p1995 tablespace reporting_index;

Table altered.

SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO'
  2  union
  3  select index_name,partition_name,status from user_ind_partitions where index_name in
  4  (select index_name from user_indexes where table_name='EMPLOYEES_PART')
  5  order by 1,2,3;

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEES_PART_PK                                                       VALID
EMPLOYEES_PART_UK1             MANAGER_100                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_200                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_300                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_400                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_500                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_600                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_700                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_800                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_900                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_MAX                              UNUSABLE
EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEE_PART_LI               P1995                                    UNUSABLE
EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEE_PART_LI               P2000                                    USABLE
EMPLOYEE_PART_LI               P2001                                    USABLE

23 rows selected.

4 拆分分区
拆分分区表的分区,通常是因为它不再符合应用程序的要求,或出于维护的原因需要拆分。最常见的原因之一是,需要简单地往表中添加一个分区,而它不是表最高端的分区,正因为如此,这需要通过拆分分区,而不是添加分区来实现。

下面的例子拆分了maxvalue分区以便为早于2003年1月的数据添加一个分区。对于本地分区索引,因为拆分操作触动了pmax分区,并创建一个新的分区(p2002),pmax分区中的行已经被拆分到两个分区中。因为一些数据可能从pmax表分区移动到新的p2002表分区,所以pmax分区的索引项是过时的。因此,在此拆分操作的情况下,这两个本地索引分区都被标记为unusable。由于新的分区以前不存在,其实没有现有的本地索引分区与它对应,所以Oracle自动创建一个索引分区,并把它标记为unusable。

与前面提到的截断和移动操作一样,拆分分区后,所有的全局分区和非分区索引全部被标记为unusable。

SQL> alter table employees_part add partition pmax values less than(maxvalue);

Table altered.

SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO'
  2  union
  3  select index_name,partition_name,status from user_ind_partitions where index_name in
  4  (select index_name from user_indexes where table_name='EMPLOYEES_PART')
  5  order by 1,2,3;

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEES_PART_PK                                                       VALID
EMPLOYEES_PART_UK1             MANAGER_100                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_200                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_300                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_400                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_500                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_600                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_700                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_800                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_900                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_MAX                              UNUSABLE
EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEE_PART_LI               P1995                                    UNUSABLE
EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEE_PART_LI               P2000                                    USABLE
EMPLOYEE_PART_LI               P2001                                    USABLE
EMPLOYEE_PART_LI               PMAX                                     UNUSABLE

24 rows selected.



SQL> alter table employees_part split partition pmax at (to_date('2003-01-01','yyyy-mm-dd')) into
  2  (partition p2002 tablespace reporting_index,partition pmax tablespace reporting_index);

Table altered.

SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO'
  2  union
  3  select index_name,partition_name,status from user_ind_partitions where index_name in
  4  (select index_name from user_indexes where table_name='EMPLOYEES_PART')
  5  order by 1,2,3;

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEES_PART_PK                                                       VALID
EMPLOYEES_PART_UK1             MANAGER_100                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_200                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_300                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_400                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_500                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_600                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_700                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_800                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_900                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_MAX                              UNUSABLE
EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEE_PART_LI               P1995                                    UNUSABLE
EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEE_PART_LI               P2000                                    USABLE
EMPLOYEE_PART_LI               P2001                                    USABLE
EMPLOYEE_PART_LI               P2002                                    UNUSABLE
EMPLOYEE_PART_LI               PMAX                                     UNUSABLE

25 rows selected.
< ?pre>
要强调的重要注意事项是,如果某个实质上往表中添加分区的分区拆分操作是必要的,因为需要一个高端分区来保存某种形式的默认数据,即使只是添加一个空分区的分区拆分操作,也可能会花费相当多的时间。因为Oracle需要分析现有的分区中的每一行,以便有效地执行正确的拆分。在这种情况下,对于指定用maxvalue指定了高端值的表,在高端分区以下,添加一个未被使用且始终为空的“虚拟”分区可能是有益的。那么,如果添加历史分区到表中,你可以始使用空的“虚拟”分区来拆分分区。这提供了两个关键的好处:首先,分区拆分操作会很快,因为没有需要分析的数据;其次,也没有索引将被标记为不可用,因为被拆分的分区没有数据,而新的分区也没有数据。

查看下面的创建表的DDL语句。对于employees_part表,员工离开了公司以后,他们的记录中的hire_date列被修改为maxvalue并留在表中作为历史记录。在这种情况下,pmax分区中将永远有数据。当你在表的pmax分区上执行分区拆分以添加今后几年的分区时,这么做总是会花时间的,而底层索引分区将标记为unusable。通过把p9999分区创建为“虚拟”分区,你绝不会把任何行添加到这个分区中。那么,当你拆分p9999分区来添加2001年及以后年份的数据分区时,它始终是在一个空的分区上进行拆分。因为拆分操作发生在空的分区上面,所以拆分操作将很快完成,而所有底层的本地索引分区将继续可用。
create table employees_part
(
employee_id number(6) not null,
first_name varchar2(20),
last_name varchar2(25) not null,
email varchar2(25) not null,
phone_numbr varchar2(20),
hire_date date not null,
job_id varchar2(10) not null,
salary number(8,2),
commission_pct number(2,2),
manager_id number(6),
department_id number(4),
constraint employees_part_pk primary key(employee_id,hire_date)
)
partition by range(hire_date)
(
partition p1990 values less than(to_date('1991-01-01','yyyy-mm-dd')),
partition p1991 values less than(to_date('1992-01-01','yyyy-mm-dd')),
partition p1992 values less than(to_date('1993-01-01','yyyy-mm-dd')),
partition p1993 values less than(to_date('1994-01-01','yyyy-mm-dd')),
partition p1994 values less than(to_date('1995-01-01','yyyy-mm-dd')),
partition p1995 values less than(to_date('1996-01-01','yyyy-mm-dd')),
partition p1996 values less than(to_date('1997-01-01','yyyy-mm-dd')),
partition p1997 values less than(to_date('1998-01-01','yyyy-mm-dd')),
partition p1998 values less than(to_date('1999-01-01','yyyy-mm-dd')),
partition p1999 values less than(to_date('2000-01-01','yyyy-mm-dd')),
partition p2000 values less than(to_date('2001-01-01','yyyy-mm-dd')),
partition p9999 values less than(to_date('9999-12-31','yyyy-mm-dd')),
partition pmax values less than(maxvalue)
);

5 交换分区
在数据仓库环境中,交换分区进行大批量数据加载特别常见。因为数据被加载到一个独立的表中,所以在加载操作期间读取操作不会受到影响。然后做一个分区交换,这实质上是对数据字典的修改,把一个独立的表段重新指向一个分区表的一部分,并把相关受影响的(原)表分区指向一个独立的表段。

分区交换与分区移动是类似的,只有受影响的本地分区索引的交换分区被标记为unusable。对于全局分区和非分区索引,你可以看到整个索引都已被标记为unusable。

SQL> alter table employees_part exchange partition p1995 with table employees_part_exch;

Table altered.


SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO'
  2  union
  3  select index_name,partition_name,status from user_ind_partitions where index_name in
  4  (select index_name from user_indexes where table_name='EMPLOYEES_PART')
  5  order by 1,2,3;

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEES_PART_PK                                                       UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_100                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_200                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_300                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_400                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_500                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_600                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_700                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_800                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_900                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_MAX                              UNUSABLE
EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEE_PART_LI               P1995                                    UNUSABLE
EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEE_PART_LI               P2000                                    USABLE
EMPLOYEE_PART_LI               P2001                                    USABLE
EMPLOYEE_PART_LI               P2002                                    USABLE
EMPLOYEE_PART_LI               PMAX                                     USABLE

25 rows selected.

6 删除分区
删除分区,通常发生在基于日期或时间戳的分区表中,因为有些数据已经过期,数据库不再需要这些数据了。对于本地分区索引,删除某个分区对其余的本地索引分区没有任何影响。所有本地分区索引保持在可用(usable)状态。然而,对于全局范围内分区和非分区索引,将再次把整个索引标记为不可用,因为Oracle无法确定这些索引中的哪些行已通过删除分区操作被删除了。

SQL> alter table employees_part drop partition p1995;

Table altered.

SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO'
  2  union
  3  select index_name,partition_name,status from user_ind_partitions where index_name in
  4  (select index_name from user_indexes where table_name='EMPLOYEES_PART')
  5  order by 1,2,3;

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEES_PART_PK                                                       UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_100                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_200                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_300                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_400                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_500                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_600                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_700                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_800                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_900                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_MAX                              UNUSABLE
EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEE_PART_LI               P2000                                    USABLE
EMPLOYEE_PART_LI               P2001                                    USABLE
EMPLOYEE_PART_LI               P2002                                    USABLE
EMPLOYEE_PART_LI               PMAX                                     USABLE

24 rows selected.

7 合并分区
合并分区操作本质上是分区拆分的逆操作,正如分区拆分操作,执行分区合并也是为了满足某些应用程序要求或是由于维护的原因。

下面的例子将把p2002和pmax分区全并成一个pmax分区。在这种情况下,两个分区中的所有行实质上被合并到一个新的分区。对于本地分区索引,它有一个匹配pmax的索引分区。因为分区合并改变了分区中行的组成,本地分区索引的pmax分区已被标记为unusable.

因为全局分区索引和非分区索引没有表分区组成的信息,所以整个索引又被标记为unusable.

SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO'
  2  union
  3  select index_name,partition_name,status from user_ind_partitions where index_name in
  4  (select index_name from user_indexes where table_name='EMPLOYEES_PART')
  5  order by 1,2,3;

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEES_PART_PK                                                       UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_100                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_200                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_300                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_400                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_500                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_600                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_700                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_800                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_900                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_MAX                              UNUSABLE
EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEE_PART_LI               P1995                                    USABLE
EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEE_PART_LI               P2000                                    USABLE
EMPLOYEE_PART_LI               P2001                                    USABLE
EMPLOYEE_PART_LI               P2002                                    USABLE
EMPLOYEE_PART_LI               PMAX                                     USABLE

25 rows selected.


SQL> alter table employees_part merge partitions p2002,pmax into partition pmax;

Table altered.

SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO'
  2  union
  3  select index_name,partition_name,status from user_ind_partitions where index_name in
  4  (select index_name from user_indexes where table_name='EMPLOYEES_PART')
  5  order by 1,2,3;

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEES_PART_PK                                                       UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_100                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_200                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_300                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_400                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_500                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_600                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_700                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_800                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_900                              UNUSABLE
EMPLOYEES_PART_UK1             MANAGER_MAX                              UNUSABLE

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEE_PART_LI               P1990                                    USABLE
EMPLOYEE_PART_LI               P1991                                    USABLE
EMPLOYEE_PART_LI               P1992                                    USABLE
EMPLOYEE_PART_LI               P1993                                    USABLE
EMPLOYEE_PART_LI               P1994                                    USABLE
EMPLOYEE_PART_LI               P1995                                    USABLE
EMPLOYEE_PART_LI               P1996                                    USABLE
EMPLOYEE_PART_LI               P1997                                    USABLE
EMPLOYEE_PART_LI               P1998                                    USABLE
EMPLOYEE_PART_LI               P1999                                    USABLE
EMPLOYEE_PART_LI               P2000                                    USABLE

INDEX_NAME                     PARTITION_NAME                           STATUS
------------------------------ ---------------------------------------- --------
EMPLOYEE_PART_LI               P2001                                    USABLE
EMPLOYEE_PART_LI               PMAX                                     UNUSABLE

24 rows selected.

注意:对于表的大多数分区级操作,如果受影响的分区是空的,那么这种操作不会影响任何相关的索引。

Oracle 全局分区索引

全局分区索引实质上意味着该索引与数据表有不同的分区方案,且是基于不同于数据表的一个或一组分区列进行分区的。这主要是为了提高数据库中数据查询的性能。基于用户对给定表的查询,为提高查询性能,可以在给定的查询列上创建全局分区的索引。

可以创建以下几种类型的全局分区索引:
.范围
.哈希

为了说明基于范围的全局分区索引,假定你发现有很多的查询要访问employees表中的manager_id列,那么就可以在manager_id列上创建分区索引,它的分区完全独立于表。查看如下范围分区索引的例子:

SQL> create table employees_jy as select * from employees;

Table created.

SQL> create index employees_gi1
  2  on employees_jy(manager_id)
  3  global
  4  partition by range(manager_id)
  5  (
  6  partition manager_100 values less than(100),
  7  partition manager_200 values less than(200),
  8  partition manager_300 values less than(300),
  9  partition manager_400 values less than(400),
 10  partition manager_500 values less than(500),
 11  partition manager_600 values less than(600),
 12  partition manager_700 values less than(700),
 13  partition manager_800 values less than(800),
 14  partition manager_900 values less than(900),
 15  partition manager_max values less than(maxvalue)
 16  );

Index created.

你可以在分区表或非分区表上创建全局分区索引。换句话说,创建全局分区索引并不需要对表进行分区。正如本章后面所讨论的,因为分区表的全局分区索引维护起来不太方便,全局分区索引并不常用,所以通常很少甚至不用它来提高查询性能,特别是在非分区表中。

基于范围的全局分区索引,必须始终为索引指定一个最大值,即用maxvalue作为最大值。这保证了新插入到相应表的任何数据将在分局分区索引中有地方保存。换句话说,对于全局分区索引,它永远不会有“越界”的情况。如果不在全局分区索引中指定上限分区,Oracle将不允许创建索引,若执行下列语句,就会出现以下错误提示信息:

SQL> create index employees_gi2
  2  on employees_jy(manager_id)
  3  global
  4  partition by range(manager_id)
  5  (
  6  partition manager_100 values less than(100),
  7  partition manager_200 values less than(200),
  8  partition manager_300 values less than(300),
  9  partition manager_400 values less than(400),
 10  partition manager_500 values less than(500),
 11  partition manager_600 values less than(600),
 12  partition manager_700 values less than(700),
 13  partition manager_800 values less than(800),
 14  partition manager_900 values less than(900)
 15  );
)
*
ERROR at line 15:
ORA-14021: MAXVALUE must be specified for all columns

由于每个全局分区索引吕必须包含一个上限分区,因此把分区添加到全局分区索引的唯一方式就是,使用alter index … split分区命令。例如:

SQL> alter index employees_gi1 split partition manager_max at(1000) into (partition manager_max,partition manager_1000);

Index altered.


SQL> select partition_name,status from user_ind_partitions where index_name='EMPLOYEES_GI1';

PARTITION_NAME                                                                                                                   STATUS
-------------------------------------------------------------------------------------------------------------------------------- --------
MANAGER_100                                                                                                                      USABLE
MANAGER_1000                                                                                                                     USABLE
MANAGER_200                                                                                                                      USABLE
MANAGER_300                                                                                                                      USABLE
MANAGER_400                                                                                                                      USABLE
MANAGER_500                                                                                                                      USABLE
MANAGER_600                                                                                                                      USABLE
MANAGER_700                                                                                                                      USABLE
MANAGER_800                                                                                                                      USABLE
MANAGER_900                                                                                                                      USABLE
MANAGER_MAX                                                                                                                      USABLE

11 rows selected.

SQL>

还可以删除全局分区索引的部分分区。然而,这样做时,如果被删除的分区包含索引条目,上限比它高的相邻分区就被标记为不可用。在下面的代码中,查询了删除分区manager_200前该索引各分区的状态:

SQL> select partition_name,status from user_ind_partitions where index_name='EMPLOYEES_GI1';

PARTITION_NAME                                                                                                                   STATUS
-------------------------------------------------------------------------------------------------------------------------------- --------
MANAGER_100                                                                                                                      USABLE
MANAGER_1000                                                                                                                     USABLE
MANAGER_200                                                                                                                      USABLE
MANAGER_300                                                                                                                      USABLE
MANAGER_400                                                                                                                      USABLE
MANAGER_500                                                                                                                      USABLE
MANAGER_600                                                                                                                      USABLE
MANAGER_700                                                                                                                      USABLE
MANAGER_800                                                                                                                      USABLE
MANAGER_900                                                                                                                      USABLE
MANAGER_MAX                                                                                                                      USABLE

11 rows selected.

然后删除分区manager_200

SQL> alter index employees_gi1 drop partition manager_200;

Index altered.

当再次查询user_ind_partitions时,你可以看到数据库把上限更高的相邻分区标记为unusable状态。

SQL> select partition_name,status from user_ind_partitions where index_name='EMPLOYEES_GI1';

PARTITION_NAME                                                                                                                   STATUS
-------------------------------------------------------------------------------------------------------------------------------- --------
MANAGER_100                                                                                                                      USABLE
MANAGER_1000                                                                                                                     USABLE
MANAGER_300                                                                                                                      UNUSABLE
MANAGER_400                                                                                                                      USABLE
MANAGER_500                                                                                                                      USABLE
MANAGER_600                                                                                                                      USABLE
MANAGER_700                                                                                                                      USABLE
MANAGER_800                                                                                                                      USABLE
MANAGER_900                                                                                                                      USABLE
MANAGER_MAX                                                                                                                      USABLE

10 rows selected.

一旦删除了全局索引分区,就必须执行alter index命令重建由于drop partition操作而被标记为unusable的分区。

SQL> alter index employees_gi1 rebuild partition manager_300;

Index altered.

SQL> select partition_name,status from user_ind_partitions where index_name='EMPLOYEES_GI1';

PARTITION_NAME                                                                                                                   STATUS
-------------------------------------------------------------------------------------------------------------------------------- --------
MANAGER_100                                                                                                                      USABLE
MANAGER_1000                                                                                                                     USABLE
MANAGER_300                                                                                                                      USABLE
MANAGER_400                                                                                                                      USABLE
MANAGER_500                                                                                                                      USABLE
MANAGER_600                                                                                                                      USABLE
MANAGER_700                                                                                                                      USABLE
MANAGER_800                                                                                                                      USABLE
MANAGER_900                                                                                                                      USABLE
MANAGER_MAX                                                                                                                      USABLE

10 rows selected.

因为必须在全局分区索引上用maxvalue指定的一个分区,所以永远无法删除上限最高的分区。例如:

SQL> alter index employees_gi1 drop partition manager_1000;
alter index employees_gi1 drop partition manager_1000
                                         *
ERROR at line 1:
ORA-14078: you may not drop the highest partition of a GLOBAL index

全局分区索引可以是唯一索引,也可以是非唯一索引。本章到目前为止,只创建了非唯一索引。下面列出的是在表上创建全局唯一索引分区的语句:

SQL> create unique index employees_uk1 on employees_jy(manager_id,employee_id)
  2  global
  3  partition by range(manager_id)
  4  (
  5  partition manager_100 values less than(100),
  6  partition manager_200 values less than(200),
  7  partition manager_300 values less than(300),
  8  partition manager_400 values less than(400),
  9  partition manager_500 values less than(500),
 10  partition manager_600 values less than(600),
 11  partition manager_700 values less than(700),
 12  partition manager_800 values less than(800),
 13  partition manager_900 values less than(900),
 14  partition manager_max values less than(maxvalue)
 15  );

Index created.

本地分区索引可以定义为前缀或非前缀索引,而全局分区索引必须创建为前缀索引,也就是说,分区列必须在该索引的前导端。如果你试图创建全局分区的非前缀索引,就会收到以下错误 提示信息:

SQL> create unique index employees_uk1 on employees_jy(employee_id)
  2  global
  3  partition by range(manager_id)
  4  (
  5  partition manager_100 values less than(100),
  6  partition manager_200 values less than(200),
  7  partition manager_300 values less than(300),
  8  partition manager_400 values less than(400),
  9  partition manager_500 values less than(500),
 10  partition manager_600 values less than(600),
 11  partition manager_700 values less than(700),
 12  partition manager_800 values less than(800),
 13  partition manager_900 values less than(900),
 14  partition manager_max values less than(maxvalue)
 15  );
partition by range(manager_id)
                             *
ERROR at line 3:
ORA-14038: GLOBAL partitioned index must be prefixed

另一种全局分区索引类型是哈希分区索引。使用哈希分区索引通常是出于性能原因,因为这使用索引在分区之间更均匀地分布。请看下面创建基于哈希的全局分区索引的例子:

SQL> create index employees_jy_ih1 on employees_jy(department_id) global partition by hash(department_id) partitions 4;

Index created.

注意:全局分区索引必须在堆组织表上创建。而且,不能创建全局分区位图索引。

Oracle管理分区表的主键和唯一索引

管理分区表的主键和唯一索引
当需要在表上定义主键约束时,首先使用主键约束的列创建唯一索引,然后再添加约束,这通常被视为一种良好的做法。例如:

SQL> create unique index employees_part_pk on employees_part(employee_id,hire_date) local;

Index created.

SQL> alter table employees_part add constraint employees_part_pk primary key(employee_id,hire_date);

Table altered.

这样做的好处是,它允许你在必要时禁用和重新启用约束,而不必删除底层索引。当必须在一个大表上执行约束管理时,这可以节省大量的时间。在数据仓库环境中,经常有大量数据要批量加载到表中,禁用约束然后重新启用约束是很常见的操作,因为在这种情况下,在加载之前禁用约束并在加载后重新启用约束,可以节省大量的整体数据处理时间。

如果你首先创建了唯一索引,然后启用主键约束,如果禁用这个主键约束,那么你的约束和索引在数据库中仍然存在。如下面的例子所示:

SQL> alter table employees_part disable constraint employees_part_pk;

Table altered.

SQL> select i.index_name,c.constraint_type,i.partitioned from user_indexes i left join user_constraints c
  2  on (i.index_name=c.constraint_name) where i.index_name='EMPLOYEES_PART_PK';

INDEX_NAME                     CONSTRAINT_TYPE                PARTITIONED
------------------------------ ------------------------------ ----------------------------------------
EMPLOYEES_PART_PK              P                              YES

如果你用create tabel语句或单个alter table语句内联地创建主键,将同时创建底层的唯一索引。在这种情况下,如果禁用这个主键约束,你可以看到它删除了底层索引。

SQL> alter table employees_part disable constraint employees_part_pk;

Table altered.

SQL> select i.index_name,c.constraint_type,i.partitioned from user_indexes i left join user_constraints c
  2  on (i.index_name=c.constraint_name) where i.index_name='EMPLOYEES_PART_PK';
no rows selected

当对表的分区一级执行操作(如在表上执行分区拆分)时,会使用一个分区的索引变得不可用(unusable),这种情况下,本地分区索引就变得非常有用。至于主键,你可以简单地禁用主键约束(在这种情况下,底层索引保持不变),执行分区操作,再重建该分区索引,然后重新启用主键约束。这样,索引唯一需要重建的是受上述操作影响的分区。

在唯一索引最终要成为主键时,唯一索引必须包含分区列这一限制会导致另一个常见的问题,即,有时用户提出需求,不要把分区列放到表的主键列中去。如下面的例子所示,通过使用先前创建的唯一索引,就可以简单地改变员工表来创建主键约束:

SQL> alter table employees_part add constraint employees_part_pk_1 primary key(employee_id);

Table altered.

如果你的客户需求中规定,分区列(在本列是hire_date)不得作为主键的一部分,那么也可以使用相同的语法简单地创建主键约束,这同时也创建了未分区的底层索引。下面的查询显示了这个结果:

SQL> select i.index_name,c.constraint_type,i.partitioned from user_indexes i,user_constraints c
  2  where i.index_name=c.constraint_name and i.index_name='EMPLOYEES_PART_PK_1';

INDEX_NAME                     CONSTRAINT_TYPE                PARTITIONED
------------------------------ ------------------------------ ----------------------------------------
EMPLOYEES_PART_PK_1            P                              NO

你的表上确实建立了索引,但它不是分区的。这样做的好处是,解除了唯一索引必须包含分区列的限制,可以在单个employee_id列上创建“自然”的主键约束了。缺点是,现在分区表employees上有一个非分区索引。如果现在需要在该表上执行任何分区级操作,如截断分区,移动分区,或拆分分区,等等,那么整个底层非分区索引将被标记为unusable,而且必须在执行任何分区级操作后重建它。

Oracle本地分区索引

1 分区索引
分区索引与非分区索引相比,具有许多好处。使用分区索引的关键好处如下:
.性能方面的优势
.通过DML操作载入数据。
.通过DDL操作载入数据。
.用select语句查询数据。

.维护方面的好处
.重建索引。
.在分区一级把索引设置为不可用或不可见。

可以创建本地分区或全局分区的分区索引。本地分区索引只能存在于分区表,而全局分区的索引既可以在分区表创建,也可以在非分区表上创建。还可以在分区表上创建非分区索引。分区索引最常见的配置是在分区表上创建本地分区索引,只是因为这种配置的整体优势一般大于分区表上的全局分区索引和非分区索引。

注意:创建分区表上的非分区索引与创建非分区表上的非分区索引是相同的。

2 创建本地分区索引
最常见的分区索引类型是本地分区索引。本地分区索引只能在分区表上创建。顾名思义,“本地”是指索引条目和相应的数据之间有直接的关系。数据分区和索引分区之间存在一对一的关系。如果有某个按日期范围分区的表,今年每个月都有一个分区,那么对于2012年1月分区的所有数据,创建的每个索引在2012年1月分区都有相应的索引项。

2.1 最简单的形式
除LOCAL关键字外,最基本的创建本地分区索引的形式与创建非分区索引相同。

create table employees_part
(
EMPLOYEE_ID   NUMBER(6),
FIRST_NAME    VARCHAR2(20),
LAST_NAME     VARCHAR2(25),
EMAIL         VARCHAR2(25),
PHONE_NUMBER  VARCHAR2(20),
HIRE_DATE     DATE,
JOB_ID        VARCHAR2(10),
SALARY        NUMBER(8,2),
COMMISSION_PCT NUMBER(2,2),
MANAGER_ID     NUMBER(6),
DEPARTMENT_ID  NUMBER(4)
)
partition by range(hire_date)
(
   partition p01 values less than(to_date('2002-01-01','yyyy-mm-dd')),
   partition p02 values less than(to_date('2003-01-01','yyyy-mm-dd')),
   partition p03 values less than(to_date('2004-01-01','yyyy-mm-dd')),
   partition p04 values less than(to_date('2005-01-01','yyyy-mm-dd')),
   partition p05 values less than(to_date('2006-01-01','yyyy-mm-dd')),
   partition p06 values less than(to_date('2007-01-01','yyyy-mm-dd')),
   partition p07 values less than(to_date('2008-01-01','yyyy-mm-dd')),
   partition p08 values less than(to_date('2009-01-01','yyyy-mm-dd')),
   partition p09 values less than(to_date('2010-01-01','yyyy-mm-dd')),
   partition p10 values less than(to_date('2011-01-01','yyyy-mm-dd')),
   partition p11 values less than(to_date('2012-01-01','yyyy-mm-dd')),
   partition p12 values less than(to_date('2013-01-01','yyyy-mm-dd'))
);
/




SQL> create table employees_part
  2  (
  3  EMPLOYEE_ID   NUMBER(6),
  4  FIRST_NAME    VARCHAR2(20),
  5  LAST_NAME     VARCHAR2(25),
  6  EMAIL         VARCHAR2(25),
  7  PHONE_NUMBER  VARCHAR2(20),
  8  HIRE_DATE     DATE,
  9  JOB_ID        VARCHAR2(10),
 10  SALARY        NUMBER(8,2),
 11  COMMISSION_PCT NUMBER(2,2),
 12  MANAGER_ID     NUMBER(6),
 13  DEPARTMENT_ID  NUMBER(4)
 14  )
 15  partition by range(hire_date)
 16  (
 17     partition p01 values less than(to_date('2002-01-01','yyyy-mm-dd')),
 18     partition p02 values less than(to_date('2003-01-01','yyyy-mm-dd')),
 19     partition p03 values less than(to_date('2004-01-01','yyyy-mm-dd')),
 20     partition p04 values less than(to_date('2005-01-01','yyyy-mm-dd')),
 21     partition p05 values less than(to_date('2006-01-01','yyyy-mm-dd')),
 22     partition p06 values less than(to_date('2007-01-01','yyyy-mm-dd')),
 23     partition p07 values less than(to_date('2008-01-01','yyyy-mm-dd')),
 24     partition p08 values less than(to_date('2009-01-01','yyyy-mm-dd')),
 25     partition p09 values less than(to_date('2010-01-01','yyyy-mm-dd')),
 26     partition p10 values less than(to_date('2011-01-01','yyyy-mm-dd')),
 27     partition p11 values less than(to_date('2012-01-01','yyyy-mm-dd')),
 28     partition p12 values less than(to_date('2013-01-01','yyyy-mm-dd'))
 29  );
/
Table created.


SQL> insert into employees_part select * from employees;

107 rows created.

SQL> commit;

Commit complete.


SQL> create index employees_part_i1 on employees_part(hire_date) local;

Index created.

对于这个例子,Oracle创建的分区名称将与数据分区的名称相同。此外,所有分区都将在USERS表空间内创建。

根据应用程序的需求,可能需要指定各个分区的具体信息,比如下列内容:
.分区名称
.表空间名称
.存储参数

2.2 分区级的需求
如果有特定的分区级的需求,就需要在create index ddl内指定每个分区的信息。例如:

SQL> create index employees_part_i2 on employees_part(hire_date) local
  2  (
  3  partition pi01,
  4  partition pi02,
  5  partition pi03,
  6  partition pi04,
  7  partition pi05,
  8  partition pi06,
  9  partition pi07,
 10  partition pi08,
 11  partition pi09,
 12  partition pi10,
 13  partition pi11,
 14  partition pi12
 15  );

Index created.

在这个例子中,对分区名称进行了修改,在表分区名中间插入一个i来表示索引分区。为了让索引具有与表不同的分区名称,必须在create indexddl中指定每个分区的名称。还可以为每个分区指定不同的表空间,因为它代表了一年的数据。把每年的数据放在自己的表空间内,就可以把往年数据的表空间设置为只读。这有助于提高查询速度和备份速度,因为你不需要在数据库的每个备份中都备份只读表空间。

再次强调,要创建本地分区索引,必须是在分区表上创建。否则,就会出现以下错误提示信息:

SQL> create index employees_i1 on employees(hire_date) tablespace users local;
create index employees_i1 on employees(hire_date) tablespace users local
                             *
ERROR at line 1:
ORA-14016: underlying table of a LOCAL partitioned index must be partitioned

2.3 前缀和非前缀选项
可以把本地分区索引创建为前缀或非前缀的。在创建本地分区的前缀索引时,这意味着表的分区列在索引的前导端。如果分区列不在索引的前导端,就被当作非前缘索引。在Oracle的早期版本中,本地前缀索引与非前缀索引相比,在性能上有一些优势。在Oracle后来的版本中,包括版本11gR2,建立本地前缀索引的优势已经减弱。不过,如果你的数据库环境是OLTP系统,本地前缀索引比非前缀索引更有利于提高查询性能,因为为了检索某个查询所需的数据,优化器需要扫描的索引分区可能会较少。

在创建本地分区的唯一索引时,索引必须包括分区列,否则就会出现以下错误提示信息:

SQL> create unique index employees_part_pk on employees_part(employee_id) local;
create unique index employees_part_pk on employees_part(employee_id) local
                                         *
ERROR at line 1:
ORA-14039: partitioning columns must form a subset of key columns of a UNIQUE index

在唯一索引的定义中添加分区列(在本例中是hire_date)后,就可以在employees_part表上创建唯一索引了。

SQL> create unique index employees_part_pk on employees_part(employee_id,hire_date) local;

Index created.

Oracle应用程序域索引

应用程序域索引是最不为人所知且大多数开发人员和DBA也是最少使用的一种。应用域索引支持创建自己的索引结构,以实现目前Oracle数据库中不存在的新的索引类型。Oracle数据库本身实现的全文索引,就是应用程序域索引的一个很好的例子,全文索引常用来促进在大的文本项中的搜索。为了创建全文索引,需要在create index语句中包含indextype子句,如下所示:

SQL> create table test_tab(dsc clob);

Table created.

SQL> insert into test_tab values('hi,this is xiaoming');

1 row created.

SQL> commit;

Commit complete.

SQL> select * from test_tab;

DSC
--------------------------------------------------------------------------------
hi,this is xiaoming

SQL> create index test_idx on test_tab(dsc) indextype is ctxsys.context;

Index created.

SQL>
SQL> select * from test_tab where contains(dsc,'this is')>0;

no rows selected

就像收集普通索引的统计信息一样,可以调用dbms_stats.gather_index_stats存储过程来收集全文索引的统计信息。虽然我们这里只是简单地讨论了应用程序域索引,在大多数情况下,这些索引对第三方解决方案供应商有更多的用处,因为他们需要使用创新的索引解决方案来访问各类非传统的数据,如文本和图像。例如,在使用某些类型的数据,如视频剪辑时,Oracle提供的数据类型可能不太适用。此外,这些特殊类型的数据,可能需要特殊类型的操作,例如,图像中的颜色等级。你可以使用能把图像中的颜色分级的比较运算符,来定义这些特殊类型的操作。

openPower服务器搭建Oracle 19c adg

创建用户与组
创建组(在各个主机上执行)

mkgroup -'A' id='501' adms='root' oinstall
mkgroup -'A' id='502' adms='root' asmdba
mkgroup -'A' id='503' adms='root' asmoper
mkgroup -'A' id='504' adms='root' dba
mkgroup -'A' id='505' adms='root' oper
mkgroup -'A' id='506' adms='root' backdba
mkgroup -'A' id='507' adms='root' dgdba
mkgroup -'A' id='508' adms='root' racdba
mkgroup -'A' id='509' adms='root' kmdba

创建用户(在各个主机上执行)

mkuser id=601 pgrp=oinstall groups=dba,asmdba,oper,asmoper,backdba,dgdba,racdba,kmdba home=/home/oracle oracle

创建安装目录

mkdir -p /u01/app/oraInventory
mkdir -p /u01/app/oracle/product/19.3/db
mkdir -p /u01/temp

chown -R oracle:oinstall /u01
chmod -R 775 /u01

设置用户环境变量(用oracle用户来编辑.profile)

umask 022
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=/u01/app/oracle/product/19.3/db
export ORACLE_SID=hxsy
export ORACLE_UNQNAME=hxsy
export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
export NLS_DATE_FORMAT="yyyy-mm-dd hh24:mi:ss"
export PATH=.:${PATH}:$HOME/bin:$ORACLE_HOME/bin
export PATH=${PATH}:/usr/bin:/bin:/usr/bin/X11:/usr/local/bin
export PATH=${PATH}:$ORACLE_BASE/common/oracle/bin
export ORACLE_PATH=${PATH}:$ORACLE_BASE/common/oracle/sql:.:$ORACLE_HOME/rdbms/admin
export ORACLE_TERM=xterm
export TNS_ADMIN=$ORACLE_HOME/network/admin
export LD_LIBRARY_PATH=$ORACLE_HOME/lib
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:$ORACLE_HOME/oracm/lib
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/lib:/usr/lib:/usr/local/lib
export CLASSPATH=$ORACLE_HOME/JRE
export CLASSPATH=${CLASSPATH}:$ORACLE_HOME/jlib
export CLASSPATH=${CLASSPATH}:$ORACLE_HOME/rdbms/jlib
export CLASSPATH=${CLASSPATH}:$ORACLE_HOME/network/jlib
export THREADS_FLAG=native
export TEMP=/u01/tmp
export TMPDIR=/u01/tmp
export PS1=`hostname`:'$PWD'"$"

使用如下命令查看虚拟内存管理参数

vmo -L minperm%
vmo -L maxperm%
vmo -L maxclient%
vmo -L lru_file_repage
vmo -L strict_maxclient
vmo -L strict_maxperm

如果设置不合适,使用如下命令修改:

vmo -p -o minperm%=3
vmo -p -o maxperm%=90
vmo -p -o maxclient%=90
vmo -p -o lru_file_repage=0
vmo -p -o strict_maxclient=1
vmo -p -o strict_maxperm=0

检查网络参数设置
ephemeral参数:
使用命令no -a |fgrep ephemeral可以查看当前系统ephemeral参数设置,建议的参数设置如下

tcp_ephemeral_high = 65500
tcp_ephemeral_low = 9000
udp_ephemeral_high= 65500
udp_ephemeral_low = 9000

如果系统中参数设置和上述值不一样,使用命令修改:

#no -p -o tcp_ephemeral_low=9000 -o tcp_ephemeral_high=65500
#no -p -o udp_ephemeral_low=9000 -o udp_ephemeral_high=65500

使用如下命令修改网络可调整参数:

#no -p -o rfc1323=1
#no -r -o ipqmaxlen=512
#no -p -o ipqmaxlen=512
#no -p -o sb_max=4194304
#no -p -o tcp_recvspace=65536
#no -p -o tcp_sendspace=65536
#no -p -o udp_recvspace=1351680 该值是udp_sendspace的10倍,但须小于sb_max
#no -p -o udp_sendspace=135168

备注:-r表示reboot后生效,-p表示即刻生效.
检查内核参数maxuproc(建议16384)和ncargs(至少128)

#lsattr -E -l sys0 -a ncargs
#lsattr -E -l sys0 -a maxuproc

如果设置不合适使用如下命令修改:

#chdev -l sys0 -a ncargs=256
#chdev -l sys0 -a maxuproc=16384

解压数据库软件

aix1:/u01/soft$unzip -q AIX.PPC64_193000_db_home.zip -d $ORACLE_HOME

安装数据库软件
在$ORACLE_HOME/install/response目录中有一个安装rsp文件示例
配置响应文件

[oracle@ora19c ~]$ vi 19c_dbinstall.rsp
oracle.install.responseFileVersion=/oracle/install/rspfmt_dbinstall_response_schema_v19.0.0
oracle.install.option=INSTALL_DB_SWONLY
UNIX_GROUP_NAME=oinstall
INVENTORY_LOCATION=/u01/app/oraInventory
ORACLE_BASE=/u01/app/oracle
ORACLE_HOME=/u01/app/oracle/product/19.3/db
oracle.install.db.InstallEdition=EE
oracle.install.db.OSDBA_GROUP=dba
oracle.install.db.OSOPER_GROUP=oper
oracle.install.db.OSBACKUPDBA_GROUP=backdba
oracle.install.db.OSDGDBA_GROUP=dgdba
oracle.install.db.OSKMDBA_GROUP=kmdba
oracle.install.db.OSRACDBA_GROUP=racdba
oracle.install.db.rootconfig.executeRootScript=true
oracle.install.db.rootconfig.configMethod=ROOT

执行安装

openaix1:/home/oracle$$ORACLE_HOME/runInstaller -silent  -force -noconfig  -ignorePrereq  -responseFile /home/oracle/19c_dbinstall.rsp

********************************************************************************

Your platform requires the root user to perform certain pre-installation
OS preparation.  The root user should run the shell script 'rootpre.sh' before
you proceed with Oracle installation. The rootpre.sh script can be found at:
/u01/app/oracle/product/19.3/db/clone/rootpre.sh

Answer 'y' if root has run 'rootpre.sh' so you can proceed with Oracle
installation.
Answer 'n' to abort installation and then ask root to run 'rootpre.sh'.

********************************************************************************

Has 'rootpre.sh' been run by root in this machine? [y/n] (n)
y
Launching Oracle Database Setup Wizard...


 Enter password for 'root' user: 
[WARNING] [INS-13014] Target environment does not meet some optional requirements.
   CAUSE: Some of the optional prerequisites are not met. See logs for details. installActions2020-11-17_01-49-09AM.log
   ACTION: Identify the list of failed prerequisite checks from the log: installActions2020-11-17_01-49-09AM.log. Then either from the log file or from installation manual find the appropriate configuration to meet the prerequisites and fix it manually.
The response file for this session can be found at:
 /u01/app/oracle/product/19.3/db/install/response/db_2020-11-17_01-49-09AM.rsp

You can find the log of this install session at:
 /u01/tmp/InstallActions2020-11-17_01-49-09AM/installActions2020-11-17_01-49-09AM.log
Successfully Setup Software with warning(s).
Moved the install session logs to:
 /u01/app/oraInventory/logs/InstallActions2020-11-17_01-49-09AM

配置监听
创建配置监听的响应文件
在/u01/app/oracle/product/19.3/db/assistants/netca/目录有一个示例文件

aix1:/home/oracle$vi 19c_netca.rsp
"19c_netca.rsp" [New file] 

[GENERAL]
RESPONSEFILE_VERSION="19.0"
CREATE_TYPE="CUSTOM"

[oracle.net.ca]
INSTALLED_COMPONENTS={"server","net8","javavm"}
INSTALL_TYPE=""typical""
LISTENER_NUMBER=1
LISTENER_NAMES={"LISTENER"}
LISTENER_PROTOCOLS={"TCP;1521"}
LISTENER_START=""LISTENER""
NAMING_METHODS={"TNSNAMES","ONAMES","HOSTNAME"}
NSN_NUMBER=1
NSN_NAMES={"EXTPROC_CONNECTION_DATA"}
NSN_SERVICE={"PLSExtProc"}
NSN_PROTOCOLS={"TCP;HOSTNAME;1521"}


aix1:/home/oracle$netca /silent /responsefile /home/oracle/19c_netca.rsp
UnsatisfiedLinkError exception loading native library: njni19
java.lang.UnsatisfiedLinkError: njni19 (Not found in java.library.path)
java.lang.UnsatisfiedLinkError: oracle/net/common/NetGetEnv.jniGetOracleHome()Ljava/lang/String;
        at oracle.net.common.NetGetEnv.getOracleHome(Unknown Source)
        at oracle.net.ca.NetCALogger.getOracleHome(NetCALogger.java:230)
        at oracle.net.ca.NetCALogger.initOracleParameters(NetCALogger.java:215)
        at oracle.net.ca.NetCALogger.initLogger(NetCALogger.java:130)
        at oracle.net.ca.NetCA.main(NetCA.java:459)

Error: oracle/net/common/NetGetEnv.jniGetOracleHome()Ljava/lang/String;
Oracle Net Services configuration failed.  The exit code is 1


# lsdev | grep iocp
iocp0      Defined         I/O Completion Ports
# smitty iocp

# lsdev | grep iocp
iocp0      Available       I/O Completion Ports


aix1:/home/oracle$$ORACLE_HOME/bin/relink all 
writing relink log to: /u01/app/oracle/product/19.3/db/install/relinkActions2020-11-16_11-17-27PM.log

aix1:/home/oracle$netca /silent /responsefile /home/oracle/19c_netca.rsp

Parsing command line arguments:
    Parameter "silent" = true
    Parameter "responsefile" = /home/oracle/19c_netca.rsp
Done parsing command line arguments.
Oracle Net Services Configuration:
Profile configuration complete.
Oracle Net Listener Startup:
    Running Listener Control: 
      /u01/app/oracle/product/19.3/db/bin/lsnrctl start LISTENER
    Listener Control complete.
    Listener started successfully.
Listener configuration complete.
Oracle Net Services configuration successful. The exit code is 0

aix1:/home/oracle$lsnrctl status

LSNRCTL for IBM/AIX RISC System/6000: Version 19.0.0.0.0 - Production on 16-NOV-2020 23:24:53

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

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=aix1)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for IBM/AIX RISC System/6000: Version 19.0.0.0.0 - Production
Start Date                16-NOV-2020 23:23:28
Uptime                    0 days 0 hr. 1 min. 27 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /u01/app/oracle/product/19.3/db/network/admin/listener.ora
Listener Log File         /u01/app/oracle/diag/tnslsnr/aix1/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=aix1)(PORT=1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
The listener supports no services
The command completed successfully

创建数据库
创建配置数据库的响应文件
在/u01/app/oracle/product/19.3/db/assistants/dbca/目录中有一个示例文件

[oracle@ora19c install]$ cat /u01/app/oracle/product/19.3/db/assistants/dbca/dbca.rsp


aix1:/home/oracle$vi 19c_dbca.rsp
automaticMemoryManagement=TRUE
responseFileVersion=/oracle/assistants/rspfmt_dbca_response_schema_v19.0.0
templateName=General_Purpose.dbc
gdbName=hxsy
sid=hxsy
databaseConfigType=SI
createAsContainerDatabase=TRUE
numberOfPDBs=1
pdbName=hxsy1
useLocalUndoForPDBs=TRUE
pdbAdminPassword=hxsy_123456
sysPassword=hxsy_123456
systemPassword=hxsy_123456
storageType=FS
characterSet=ZHS16GBK
nationalCharacterSet=AL16UTF16
listeners=LISTENER
sampleSchema=TRUE
totalMemory 2048
databaseType=MULTIPURPOSE
automaticMemoryManagement=FALSE
totalMemory=4096

创建数据库

aix1:/home/oracle$dbca -silent  -createDatabase -responseFile /home/oracle/19c_dbca.rsp
[WARNING] [DBT-06208] The 'SYS' password entered does not conform to the Oracle recommended standards.
   CAUSE: 
a. Oracle recommends that the password entered should be at least 8 characters in length, contain at least 1 uppercase character, 1 lower case character and 1 digit [0-9].
b.The password entered is a keyword that Oracle does not recommend to be used as password
   ACTION: Specify a strong password. If required refer Oracle documentation for guidelines.
[WARNING] [DBT-06208] The 'SYSTEM' password entered does not conform to the Oracle recommended standards.
   CAUSE: 
a. Oracle recommends that the password entered should be at least 8 characters in length, contain at least 1 uppercase character, 1 lower case character and 1 digit [0-9].
b.The password entered is a keyword that Oracle does not recommend to be used as password
   ACTION: Specify a strong password. If required refer Oracle documentation for guidelines.
[WARNING] [DBT-06208] The 'PDBADMIN' password entered does not conform to the Oracle recommended standards.
   CAUSE: 
a. Oracle recommends that the password entered should be at least 8 characters in length, contain at least 1 uppercase character, 1 lower case character and 1 digit [0-9].
b.The password entered is a keyword that Oracle does not recommend to be used as password
   ACTION: Specify a strong password. If required refer Oracle documentation for guidelines.
Prepare for db operation
8% complete
Copying database files
31% complete
Creating and starting Oracle instance
32% complete
36% complete
40% complete
43% complete
46% complete
Completing Database Creation
51% complete
53% complete
54% complete
Creating Pluggable Databases
58% complete
77% complete
Executing Post Configuration Actions
100% complete
Database creation complete. For details check the logfiles at:
 /u01/app/oracle/cfgtoollogs/dbca/hxsy.
Database Information:
Global Database Name:hxsy
System Identifier(SID):hxsy
Look at the log file "/u01/app/oracle/cfgtoollogs/dbca/hxsy/hxsy.log" for further details.

给主库配置归档

SQL> archive log list
Database log mode              No Archive Mode
Automatic archival             Disabled
Archive destination            /u01/app/oracle/product/19.3/db/dbs/arch
Oldest online log sequence     5
Current log sequence           7


SQL> alter system set log_archive_dest_1='location=/u01/app/oracle/arch' scope=both sid='*';

System altered.

SQL> show parameter log_archive_for

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
log_archive_format                   string      %t_%s_%r.dbf

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

aix1:/u01/app/oracle/product/19.3/db/dbs$sqlplus / as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Mon Nov 16 16:32:33 2020
Version 19.3.0.0.0

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

Connected to an idle instance.

SQL> startup mount
ORACLE instance started.

Total System Global Area 3221222936 bytes
Fixed Size                  9303576 bytes
Variable Size             956301312 bytes
Database Buffers         2231369728 bytes
Redo Buffers               24248320 bytes
Database mounted.

SQL> alter database archivelog;

Database altered.

SQL> alter database open;

Database altered.

SQL> show pdbs;

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 HXSY1                          MOUNTED

SQL> alter pluggable database hxsy1 open;

Pluggable database altered.

SQL> show pdbs;

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 HXSY1                          READ WRITE NO

这里主库已经启用了归档

启用force logging

SQL> alter database force logging;

Database altered.

SQL> select force_logging from v$database;

FORCE_LOGGING
---------------------------------------
YES

给备库创建密码文件
这里通过复制主库的密码文件来创建备库密码文件

openaix1:/u01/app/oracle/product/19.3/db/dbs$scp oracle@aix1:/u01/app/oracle/product/19.3/db/dbs/orapwhxsy /u01/app/oracle/product/19.3/db/dbs/
oracle@aix1's password: 
orapwhxsy                                                                                                                                                                                                 100% 2048   199.4KB/s   00:00    
openaix1:/u01/app/oracle/product/19.3/db/dbs$ls -lrt
total 16
-rw-r--r--    1 oracle   oinstall       3079 May 16 2015  init.ora
-rw-r-----    1 oracle   oinstall       2048 Nov 17 16:40 orapwhxsy

给备库创建参数文件
使用主库的参数文件进行创建

SQL> create pfile from spfile;

File created.



aix1:/u01/app/oracle/product/19.3/db/dbs$cat inithxsy.ora

*.audit_file_dest='/u01/app/oracle/admin/hxsy/adump'
*.audit_trail='db'
*.compatible='19.0.0'
*.control_files='/u01/app/oracle/oradata/HXSY_DG/control01.ctl','/u01/app/oracle/oradata/HXSY_DG/control02.ctl'
*.db_block_size=8192
*.db_name='hxsy'
*.db_unique_name='hxsy_dg'
*.diagnostic_dest='/u01/app/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=hxsyXDB)'
*.enable_pluggable_database=true
*.local_listener='LISTENER_HXSY'
*.log_archive_dest_1='location=/u01/app/oracle/arch valid_for=(ALL_LOGFILES,ALL_ROLES) db_unique_name=hxsy_dg'
*.log_archive_dest_2='service=hxsy LGWR ASYNC valid_for=(online_logfiles,primary_role) db_unique_name=hxsy'
*.log_archive_config='DG_CONFIG=(hxsy,hxsy_dg)'
*.nls_language='AMERICAN'
*.nls_territory='AMERICA'
*.open_cursors=300
*.pga_aggregate_target=1024m
*.processes=2560
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=3072m
*.undo_tablespace='UNDOTBS1'
--备库以备库角色运行时需要设置的参数
*.db_file_name_convert='/u01/app/oracle/oradata/HXSY','/u01/app/oracle/oradata/HXSY_DG'
*.fal_client='hxsy_dg'
*.fal_server='hxsy'
*.log_file_name_convert='/u01/app/oracle/oradata/HXSY','/u01/app/oracle/oradata/HXSY_DG'
*.standby_file_management='auto'

在备库主机上创建参数文件

openaix1:/u01/app/oracle/product/19.3/db/dbs$vi inithxsy.ora
"inithxsy.ora" [New file] 
*.audit_file_dest='/u01/app/oracle/admin/hxsy/adump'
*.audit_trail='db'
*.compatible='19.0.0'
*.control_files='/u01/app/oracle/oradata/HXSY_DG/control01.ctl','/u01/app/oracle/oradata/HXSY_DG/control02.ctl'
*.db_block_size=8192
*.db_name='hxsy'
*.db_unique_name='hxsy_dg'
*.diagnostic_dest='/u01/app/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=hxsyXDB)'
*.enable_pluggable_database=true
*.local_listener='LISTENER_HXSY'
*.log_archive_dest_1='location=/u01/app/oracle/arch valid_for=(ALL_LOGFILES,ALL_ROLES) db_unique_name=hxsy_dg'
*.log_archive_dest_2='service=hxsy LGWR ASYNC valid_for=(online_logfiles,primary_role) db_unique_name=hxsy'
*.log_archive_config='DG_CONFIG=(hxsy,hxsy_dg)'
*.nls_language='AMERICAN'
*.nls_territory='AMERICA'
*.open_cursors=300
*.pga_aggregate_target=1024m
*.processes=2560
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=3072m
*.undo_tablespace='UNDOTBS1'
*.db_file_name_convert='/u01/app/oracle/oradata/HXSY','/u01/app/oracle/oradata/HXSY_DG'
*.fal_client='hxsy_dg'
*.fal_server='hxsy'
*.log_file_name_convert='/u01/app/oracle/oradata/HXSY','/u01/app/oracle/oradata/HXSY_DG'
*.standby_file_management='auto'

为主库和备库配置监听
主库

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = hxsy)
      (ORACLE_HOME =/u01/app/oracle/product/19.3/db)
      (GLOBAL_DBNAME=hxsy)
    )
  )

备库

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = hxsy)
      (ORACLE_HOME =/u01/app/oracle/product/19.3/db)
      (GLOBAL_DBNAME=hxsy_dg)
    )
  )

重启主库和备库的监听
主库:

aix1:/u01/app/oracle/product/19.3/db/network/admin$lsnrctl status

LSNRCTL for IBM/AIX RISC System/6000: Version 19.0.0.0.0 - Production on 16-NOV-2020 16:58:45

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

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=aix1)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for IBM/AIX RISC System/6000: Version 19.0.0.0.0 - Production
Start Date                16-NOV-2020 16:58:06
Uptime                    0 days 0 hr. 0 min. 39 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /u01/app/oracle/product/19.3/db/network/admin/listener.ora
Listener Log File         /u01/app/oracle/diag/tnslsnr/aix1/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=aix1)(PORT=1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Services Summary...
Service "hxsy" has 1 instance(s).
  Instance "hxsy", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully

备库:

openaix1:/home/oracle$lsnrctl start

LSNRCTL for IBM/AIX RISC System/6000: Version 19.0.0.0.0 - Production on 17-NOV-2020 17:01:03

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

Starting /u01/app/oracle/product/19.3/db/bin/tnslsnr: please wait...

TNSLSNR for IBM/AIX RISC System/6000: Version 19.0.0.0.0 - Production
System parameter file is /u01/app/oracle/product/19.3/db/network/admin/listener.ora
Log messages written to /u01/app/oracle/diag/tnslsnr/openaix1/listener/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=openaix1)(PORT=1521)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=openaix1)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for IBM/AIX RISC System/6000: Version 19.0.0.0.0 - Production
Start Date                17-NOV-2020 17:01:04
Uptime                    0 days 0 hr. 0 min. 0 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /u01/app/oracle/product/19.3/db/network/admin/listener.ora
Listener Log File         /u01/app/oracle/diag/tnslsnr/openaix1/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=openaix1)(PORT=1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Services Summary...
Service "hxsy_dg" has 1 instance(s).
  Instance "hxsy", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully

为主库和备库创建Oracle Net服务名
主库:

HXSY =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.24.117)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = hxsy)
    )
  )


HXSY_DG =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.24.116)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = hxsy_dg)
      (UR=A)
    )
  )

备库:
使用备份创建备库

openaix1:/u01/app/oracle/oradata$sqlplus / as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Tue Nov 17 17:07:09 2020
Version 19.3.0.0.0

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

Connected to an idle instance.

SQL> startup nomount
ORACLE instance started.

Total System Global Area 3221222936 bytes
Fixed Size                  9242136 bytes
Variable Size             754974720 bytes
Database Buffers         2449473536 bytes
Redo Buffers                7532544 bytes

aix1:/u01/app/oracle/product/19.3/db/dbs$rman target sys/hxsy_123456@hxsy auxiliary sys/hxsy_123456@hxsy_dg

Recovery Manager: Release 19.0.0.0.0 - Production on Mon Nov 16 17:23:03 2020
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

connected to target database: HXSY (DBID=1728588152)
connected to auxiliary database: HXSY (not mounted)

RMAN> duplicate target database for standby from active database nofilenamecheck;

Starting Duplicate Db at 2020-11-16 17:23:12
using target database control file instead of recovery catalog
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=2420 device type=DISK

contents of Memory Script:
{
   backup as copy reuse
   passwordfile auxiliary format  '/u01/app/oracle/product/19.3/db/dbs/orapwhxsy'   ;
}
executing Memory Script

Starting backup at 2020-11-16 17:23:14
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=2908 device type=DISK
Finished backup at 2020-11-16 17:23:16

contents of Memory Script:
{
   restore clone from service  'hxsy' standby controlfile;
}
executing Memory Script

Starting restore at 2020-11-16 17:23:16
using channel ORA_AUX_DISK_1

channel ORA_AUX_DISK_1: starting datafile backup set restore
channel ORA_AUX_DISK_1: using network backup set from service hxsy
channel ORA_AUX_DISK_1: restoring control file
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:04
output file name=/u01/app/oracle/oradata/HXSY_DG/control01.ctl
output file name=/u01/app/oracle/oradata/HXSY_DG/control02.ctl
Finished restore at 2020-11-16 17:23:22

contents of Memory Script:
{
   sql clone 'alter database mount standby database';
}
executing Memory Script

sql statement: alter database mount standby database

contents of Memory Script:
{
   set newname for tempfile  1 to 
 "/u01/app/oracle/oradata/HXSY_DG/temp01.dbf";
   set newname for tempfile  2 to 
 "/u01/app/oracle/oradata/HXSY_DG/pdbseed/temp012020-11-17_00-11-36-085-AM.dbf";
   set newname for tempfile  3 to 
 "/u01/app/oracle/oradata/HXSY_DG/hxsy1/temp01.dbf";
   switch clone tempfile all;
   set newname for datafile  1 to 
 "/u01/app/oracle/oradata/HXSY_DG/system01.dbf";
   set newname for datafile  3 to 
 "/u01/app/oracle/oradata/HXSY_DG/sysaux01.dbf";
   set newname for datafile  4 to 
 "/u01/app/oracle/oradata/HXSY_DG/undotbs01.dbf";
   set newname for datafile  5 to 
 "/u01/app/oracle/oradata/HXSY_DG/pdbseed/system01.dbf";
   set newname for datafile  6 to 
 "/u01/app/oracle/oradata/HXSY_DG/pdbseed/sysaux01.dbf";
   set newname for datafile  7 to 
 "/u01/app/oracle/oradata/HXSY_DG/users01.dbf";
   set newname for datafile  8 to 
 "/u01/app/oracle/oradata/HXSY_DG/pdbseed/undotbs01.dbf";
   set newname for datafile  9 to 
 "/u01/app/oracle/oradata/HXSY_DG/hxsy1/system01.dbf";
   set newname for datafile  10 to 
 "/u01/app/oracle/oradata/HXSY_DG/hxsy1/sysaux01.dbf";
   set newname for datafile  11 to 
 "/u01/app/oracle/oradata/HXSY_DG/hxsy1/undotbs01.dbf";
   set newname for datafile  12 to 
 "/u01/app/oracle/oradata/HXSY_DG/hxsy1/users01.dbf";
   restore
   from  nonsparse   from service 
 'hxsy'   clone database
   ;
   sql 'alter system archive log current';
}
executing Memory Script

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

renamed tempfile 1 to /u01/app/oracle/oradata/HXSY_DG/temp01.dbf in control file
renamed tempfile 2 to /u01/app/oracle/oradata/HXSY_DG/pdbseed/temp012020-11-17_00-11-36-085-AM.dbf in control file
renamed tempfile 3 to /u01/app/oracle/oradata/HXSY_DG/hxsy1/temp01.dbf in control file

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

Starting restore at 2020-11-16 17:23:32
using channel ORA_AUX_DISK_1

channel ORA_AUX_DISK_1: starting datafile backup set restore
channel ORA_AUX_DISK_1: using network backup set from service hxsy
channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_AUX_DISK_1: restoring datafile 00001 to /u01/app/oracle/oradata/HXSY_DG/system01.dbf
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:25
channel ORA_AUX_DISK_1: starting datafile backup set restore
channel ORA_AUX_DISK_1: using network backup set from service hxsy
channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_AUX_DISK_1: restoring datafile 00003 to /u01/app/oracle/oradata/HXSY_DG/sysaux01.dbf
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:16
channel ORA_AUX_DISK_1: starting datafile backup set restore
channel ORA_AUX_DISK_1: using network backup set from service hxsy
channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_AUX_DISK_1: restoring datafile 00004 to /u01/app/oracle/oradata/HXSY_DG/undotbs01.dbf
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:07
channel ORA_AUX_DISK_1: starting datafile backup set restore
channel ORA_AUX_DISK_1: using network backup set from service hxsy
channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_AUX_DISK_1: restoring datafile 00005 to /u01/app/oracle/oradata/HXSY_DG/pdbseed/system01.dbf
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:15
channel ORA_AUX_DISK_1: starting datafile backup set restore
channel ORA_AUX_DISK_1: using network backup set from service hxsy
channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_AUX_DISK_1: restoring datafile 00006 to /u01/app/oracle/oradata/HXSY_DG/pdbseed/sysaux01.dbf
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:16
channel ORA_AUX_DISK_1: starting datafile backup set restore
channel ORA_AUX_DISK_1: using network backup set from service hxsy
channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_AUX_DISK_1: restoring datafile 00007 to /u01/app/oracle/oradata/HXSY_DG/users01.dbf
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:01
channel ORA_AUX_DISK_1: starting datafile backup set restore
channel ORA_AUX_DISK_1: using network backup set from service hxsy
channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_AUX_DISK_1: restoring datafile 00008 to /u01/app/oracle/oradata/HXSY_DG/pdbseed/undotbs01.dbf
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:03
channel ORA_AUX_DISK_1: starting datafile backup set restore
channel ORA_AUX_DISK_1: using network backup set from service hxsy
channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_AUX_DISK_1: restoring datafile 00009 to /u01/app/oracle/oradata/HXSY_DG/hxsy1/system01.dbf
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:15
channel ORA_AUX_DISK_1: starting datafile backup set restore
channel ORA_AUX_DISK_1: using network backup set from service hxsy
channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_AUX_DISK_1: restoring datafile 00010 to /u01/app/oracle/oradata/HXSY_DG/hxsy1/sysaux01.dbf
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:15
channel ORA_AUX_DISK_1: starting datafile backup set restore
channel ORA_AUX_DISK_1: using network backup set from service hxsy
channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_AUX_DISK_1: restoring datafile 00011 to /u01/app/oracle/oradata/HXSY_DG/hxsy1/undotbs01.dbf
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:03
channel ORA_AUX_DISK_1: starting datafile backup set restore
channel ORA_AUX_DISK_1: using network backup set from service hxsy
channel ORA_AUX_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_AUX_DISK_1: restoring datafile 00012 to /u01/app/oracle/oradata/HXSY_DG/hxsy1/users01.dbf
channel ORA_AUX_DISK_1: restore complete, elapsed time: 00:00:02
Finished restore at 2020-11-16 17:25:31

sql statement: alter system archive log current

contents of Memory Script:
{
   switch clone datafile all;
}
executing Memory Script

datafile 1 switched to datafile copy
input datafile copy RECID=4 STAMP=1056734739 file name=/u01/app/oracle/oradata/HXSY_DG/system01.dbf
datafile 3 switched to datafile copy
input datafile copy RECID=5 STAMP=1056734739 file name=/u01/app/oracle/oradata/HXSY_DG/sysaux01.dbf
datafile 4 switched to datafile copy
input datafile copy RECID=6 STAMP=1056734740 file name=/u01/app/oracle/oradata/HXSY_DG/undotbs01.dbf
datafile 5 switched to datafile copy
input datafile copy RECID=7 STAMP=1056734740 file name=/u01/app/oracle/oradata/HXSY_DG/pdbseed/system01.dbf
datafile 6 switched to datafile copy
input datafile copy RECID=8 STAMP=1056734740 file name=/u01/app/oracle/oradata/HXSY_DG/pdbseed/sysaux01.dbf
datafile 7 switched to datafile copy
input datafile copy RECID=9 STAMP=1056734740 file name=/u01/app/oracle/oradata/HXSY_DG/users01.dbf
datafile 8 switched to datafile copy
input datafile copy RECID=10 STAMP=1056734740 file name=/u01/app/oracle/oradata/HXSY_DG/pdbseed/undotbs01.dbf
datafile 9 switched to datafile copy
input datafile copy RECID=11 STAMP=1056734740 file name=/u01/app/oracle/oradata/HXSY_DG/hxsy1/system01.dbf
datafile 10 switched to datafile copy
input datafile copy RECID=12 STAMP=1056734740 file name=/u01/app/oracle/oradata/HXSY_DG/hxsy1/sysaux01.dbf
datafile 11 switched to datafile copy
input datafile copy RECID=13 STAMP=1056734740 file name=/u01/app/oracle/oradata/HXSY_DG/hxsy1/undotbs01.dbf
datafile 12 switched to datafile copy
input datafile copy RECID=14 STAMP=1056734740 file name=/u01/app/oracle/oradata/HXSY_DG/hxsy1/users01.dbf
Finished Duplicate Db at 2020-11-16 17:25:45
openaix1:/u01/app/oracle/oradata/HXSY_DG$sqlplus / as sysdba 

SQL*Plus: Release 19.0.0.0.0 - Production on Tue Nov 17 17:26:54 2020
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> select instance_name,status from v$instance;

INSTANCE_NAME    STATUS
---------------- ------------
hxsy             MOUNTED

SQL> show parameter db_unique_name

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_unique_name                       string      hxsy_dg

SQL> select name from v$datafile;

NAME
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/HXSY_DG/system01.dbf
/u01/app/oracle/oradata/HXSY_DG/sysaux01.dbf
/u01/app/oracle/oradata/HXSY_DG/undotbs01.dbf
/u01/app/oracle/oradata/HXSY_DG/pdbseed/system01.dbf
/u01/app/oracle/oradata/HXSY_DG/pdbseed/sysaux01.dbf
/u01/app/oracle/oradata/HXSY_DG/users01.dbf
/u01/app/oracle/oradata/HXSY_DG/pdbseed/undotbs01.dbf
/u01/app/oracle/oradata/HXSY_DG/hxsy1/system01.dbf
/u01/app/oracle/oradata/HXSY_DG/hxsy1/sysaux01.dbf
/u01/app/oracle/oradata/HXSY_DG/hxsy1/undotbs01.dbf
/u01/app/oracle/oradata/HXSY_DG/hxsy1/users01.dbf

11 rows selected.

对物理备库创建备重做日志文件
查询主库的联机重做日志文件,备重做日志文件的大小应该与主库联机重做日志文件的大小相同,备重做日志文件组的数量应该比主库联机重做日志文件组多一组,计算公式为

(maximum # of logfiles +1) * maximum # of threads 
aix1:/u01/app/oracle/product/19.3/db/dbs$sqlplus sys/hxsy_123456@hxsy as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Mon Nov 16 17:28:21 2020
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>  select member from v$logfile;

MEMBER
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/HXSY/redo03.log
/u01/app/oracle/oradata/HXSY/redo02.log
/u01/app/oracle/oradata/HXSY/redo01.log


SQL> select group#,thread#,bytes/1024/1024 from v$log;

    GROUP#    THREAD# BYTES/1024/1024
---------- ---------- ---------------
         1          1             200
         2          1             200
         3          1             200



SQL> select member from v$logfile;

MEMBER
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/HXSY_DG/redo03.log
/u01/app/oracle/oradata/HXSY_DG/redo02.log
/u01/app/oracle/oradata/HXSY_DG/redo01.log

SQL> select group#,thread#,bytes/1024/1024 from v$log;

    GROUP#    THREAD# BYTES/1024/1024
---------- ---------- ---------------
         1          1             200
         3          1             200
         2          1             200

备库:

SQL> alter database add standby logfile thread 1 group 4('/u01/app/oracle/oradata/HXSY_DG/redo04.log') size 200M;

Database altered.

SQL> alter database add standby logfile thread 1 group 5('/u01/app/oracle/oradata/HXSY_DG/redo05.log') size 200M;

Database altered.

SQL> alter database add standby logfile thread 1 group 6('/u01/app/oracle/oradata/HXSY_DG/redo06.log') size 200M;

Database altered.

SQL> alter database add standby logfile thread 1 group 7('/u01/app/oracle/oradata/HXSY_DG/redo07.log') size 200M;

Database altered.

主库:

SQL> alter database add standby logfile thread 1 group 4('/u01/app/oracle/oradata/HXSY/redo04.log') size 200M;

Database altered.

SQL> alter database add standby logfile thread 1 group 5('/u01/app/oracle/oradata/HXSY/redo05.log') size 200M;

Database altered.

SQL> alter database add standby logfile thread 1 group 6('/u01/app/oracle/oradata/HXSY/redo06.log') size 200M;

Database altered.

SQL> alter database add standby logfile thread 1 group 7('/u01/app/oracle/oradata/HXSY/redo07.log') size 200M;

Database altered.

设置主库相关初始化参数

log_archive_config='DG_CONFIG=(hxsy,hxsy_dg)'
log_archive_dest_1='LOCATION=/u01/app/oracle/arch valid_for=(ALL_LOGFILES,ALL_ROLES) db_unique_name=hxsy'
log_archive_dest_2='SERVICE=hxsy_dg LGWR ASYNC valid_for=(ONLINE_LOGFILES,PRIMARY_ROLE) db_unique_name=hxsy_dg'
log_archive_dest_state_1=enable
log_archive_dest_state_2=enable
remote_login_passwordfile=exclusive
log_archive_format= %t_%s_%r.dbf
log_archive_max_processes=30

主库以备库角色运行时需要额外设置的参数。这些参数当主库被转换为备库角色运行时生效:

fal_server='hxsy_dg'
fal_client='hxsy'
db_file_name_convert='/u01/app/oracle/oradata/HXSY_DG', '/u01/app/oracle/oradata/HXSY'
log_file_name_convert='/u01/app/oracle/oradata/HXSY_DG', '/u01/app/oracle/oradata/HXSY'
standby_file_management='auto'


SQL> alter system set log_archive_dest_1='LOCATION=/u01/app/oracle/arch valid_for=(ALL_LOGFILES,ALL_ROLES) db_unique_name=hxsy' scope=both sid='*';

System altered.

SQL> alter system set log_archive_dest_2='SERVICE=hxsy_dg LGWR ASYNC valid_for=(ONLINE_LOGFILES,PRIMARY_ROLE) db_unique_name=hxsy_dg'scope=both sid='*';

System altered.

SQL> alter system set log_archive_dest_state_1=enable scope=both sid='*';

System altered.

SQL> alter system set log_archive_dest_state_2=enable scope=both sid='*';

System altered.


SQL> alter system set log_archive_max_processes=30 scope=both sid='*';

System altered.

SQL> alter system set fal_server='hxsy_dg' scope=both sid='*';

System altered.

SQL> alter system set fal_client='hxsy' scope=both sid='*';

System altered.

SQL> alter system set db_file_name_convert='/u01/app/oracle/oradata/HXSY_DG', '/u01/app/oracle/oradata/HXSY' scope=spfile sid='*';

System altered.

SQL> alter system set log_file_name_convert='/u01/app/oracle/oradata/HXSY_DG', '/u01/app/oracle/oradata/HXSY' scope=spfile sid='*';

System altered.

SQL> alter system set standby_file_management='auto' scope=both sid='*';

System altered.


SQL> alter system set log_archive_config='DG_CONFIG=(hxsy,hxsy_dg)' scope=both sid='*';

System altered.



SQL> select name, database_role, open_mode from gv$database;

NAME      DATABASE_ROLE    OPEN_MODE
--------- ---------------- --------------------
HXSY      PRIMARY          READ WRITE


SQL> select name, database_role, open_mode from gv$database;

NAME      DATABASE_ROLE    OPEN_MODE
--------- ---------------- --------------------
HXSY      PHYSICAL STANDBY READ ONLY

使用alter database语句来启用实时应用功能:
.对于物理备库执行alter database recover managed standby database(在Oracle 12.1中需要指定current logfile子句来启用实时应用,但在12.2中不再需要)。

在备库节点上执行实时重做应用

SQL> alter database recover managed standby database using current logfile disconnect from session;

Database altered.

alert日志信息如下

# tail -f /u01/app/oracle/diag/rdbms/hxsy_dg/hxsy/trace/alert_hxsy.log
ORA-01157: cannot identify/lock data file 202 - see DBWR trace file
ORA-01110: data file 202: '/u01/app/oracle/oradata/HXSY_DG/pdbseed/temp012020-11-17_00-11-36-085-AM.dbf'
2020-11-17T17:47:58.239174-06:00
File 202 not verified due to error ORA-01157
2020-11-17T17:47:58.390428-06:00
PDB$SEED(2):Re-creating tempfile /u01/app/oracle/oradata/HXSY_DG/pdbseed/temp012020-11-17_00-11-36-085-AM.dbf
2020-11-17T17:47:59.013123-06:00
PDB$SEED(2):Opening pdb with no Resource Manager plan active
Physical standby database opened for read only access.
Completed: alter database open
2020-11-17T17:50:46.966690-06:00
Warning: ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE has been deprecated.
Warning: ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE has been deprecated.
alter database recover managed standby database using current logfile disconnect from session
2020-11-17T17:50:47.069179-06:00
Attempt to start background Managed Standby Recovery process (hxsy)
Starting background process MRP0
2020-11-17T17:50:47.296690-06:00
MRP0 started with pid=67, OS id=10682718 
2020-11-17T17:50:47.329349-06:00
Background Managed Standby Recovery process started (hxsy)
2020-11-17T17:50:52.560871-06:00
 Started logmerger process
2020-11-17T17:50:52.734970-06:00

IM on ADG: Start of Empty Journal 

IM on ADG: End of Empty Journal 
PR00 (PID:12190072): Managed Standby Recovery starting Real Time Apply
max_pdb is 3
2020-11-17T17:50:54.165887-06:00
Parallel Media Recovery started with 8 slaves
2020-11-17T17:50:54.389175-06:00
stopping change tracking
2020-11-17T17:50:54.609199-06:00
PR00 (PID:12190072): Media Recovery Log /u01/app/oracle/arch/1_7_1056672314.dbf
2020-11-17T17:50:54.799176-06:00
PR00 (PID:12190072): Media Recovery Log /u01/app/oracle/arch/1_8_1056672314.dbf
2020-11-17T17:50:54.877923-06:00
TT02 (PID:12779914): Waiting for all non-current ORLs to be archived
2020-11-17T17:50:54.987923-06:00
TT02 (PID:12779914): All non-current ORLs have been archived
2020-11-17T17:50:55.311006-06:00
Completed: alter database recover managed standby database using current logfile disconnect from session
2020-11-17T17:50:55.335874-06:00
PR00 (PID:12190072): Media Recovery Waiting for T-1.S-9 (in transit)
2020-11-17T17:50:55.376975-06:00
Recovery of Online Redo Log: Thread 1 Group 4 Seq 9 Reading mem 0
2020-11-17T17:50:55.412407-06:00
  Mem# 0: /u01/app/oracle/oradata/HXSY_DG/redo04.log

在主库创建表空间test

SQL> create tablespace test datafile '/u01/app/oracle/oradata/HXSY/test01.dbf' size 50M;

Tablespace created.


SQL>  select tablespace_name from dba_tablespaces;

TABLESPACE_NAME
------------------------------
SYSTEM
SYSAUX
UNDOTBS1
TEMP
USERS
TEST

6 rows selected.

SQL> select con_id,ts#,name from v$tablespace;

    CON_ID        TS# NAME
---------- ---------- ------------------------------
         1          1 SYSAUX
         1          0 SYSTEM
         1          2 UNDOTBS1
         1          4 USERS
         1          3 TEMP
         2          0 SYSTEM
         2          1 SYSAUX
         2          2 UNDOTBS1
         2          3 TEMP
         3          0 SYSTEM
         3          1 SYSAUX

    CON_ID        TS# NAME
---------- ---------- ------------------------------
         3          2 UNDOTBS1
         3          3 TEMP
         3          5 USERS
         1          6 TEST

15 rows selected.

SQL> select ts#,name from v$datafile where ts#=6 and con_id=1;

       TS# NAME
---------- --------------------------------------------------
         6 /u01/app/oracle/oradata/HXSY/test01.dbf

备库alert日志如下:

Recovery of Online Redo Log: Thread 1 Group 4 Seq 9 Reading mem 0
2020-11-17T17:50:55.412407-06:00
  Mem# 0: /u01/app/oracle/oradata/HXSY_DG/redo04.log
2020-11-17T17:52:48.412685-06:00
Recovery created file /u01/app/oracle/oradata/HXSY_DG/test01.dbf
2020-11-17T17:52:48.453155-06:00
Errors in file /u01/app/oracle/diag/rdbms/hxsy_dg/hxsy/trace/hxsy_dbw0_7602670.trc:
ORA-01157: cannot identify/lock data file 203 - see DBWR trace file
ORA-01110: data file 203: '/u01/app/oracle/oradata/HXSY_DG/hxsy1/temp01.dbf'
ORA-27037: unable to obtain file status
IBM AIX RISC System/6000 Error: 2: No such file or directory
Additional information: 7
Successfully added datafile 13 to media recovery
Datafile #13: '/u01/app/oracle/oradata/HXSY_DG/test01.dbf'
2020-11-17T17:53:13.126690-06:00
Control autobackup written to DISK device

备库:

SQL> select tablespace_name from dba_tablespaces;

TABLESPACE_NAME
------------------------------
SYSTEM
SYSAUX
UNDOTBS1
TEMP
USERS
TEST

6 rows selected.

SQL> select con_id,ts#,name from v$tablespace;

    CON_ID        TS# NAME
---------- ---------- ------------------------------
         1          1 SYSAUX
         1          0 SYSTEM
         1          2 UNDOTBS1
         1          4 USERS
         1          3 TEMP
         2          0 SYSTEM
         2          1 SYSAUX
         2          2 UNDOTBS1
         2          3 TEMP
         3          0 SYSTEM
         3          1 SYSAUX

    CON_ID        TS# NAME
---------- ---------- ------------------------------
         3          2 UNDOTBS1
         3          3 TEMP
         3          5 USERS
         1          6 TEST

15 rows selected.

SQL> select ts#,name from v$datafile where ts#=6 and con_id=1;

       TS# NAME
---------- --------------------------------------------------
         6 /u01/app/oracle/oradata/HXSY_DG/test01.dbf

验证
主库:

SQL> create table t1 as select * from dba_users;

Table created.

SQL> select count(*) from t1;

  COUNT(*)
----------
        36


SQL> create table t2(id number(20),name varchar2(20));

Table created.

SQL> insert into t2 values(1,'jy');

1 row created.

SQL> commit;

Commit complete.

SQL> update t2 set name='hy' where id=1;

1 row updated.

SQL> commit;

Commit complete.

SQL> delete from t2;

1 row deleted.

SQL> commit;

Commit complete.

SQL> create table t3(id number(20),name varchar2(20)) tablespace test;

Table created.

SQL> insert into t3 values(1,'jy');

1 row created.

SQL> commit;

Commit complete.

备库

SQL> select count(*) from t1;

  COUNT(*)
----------
        36

SQL> desc t2;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER(20)
 NAME                                               VARCHAR2(20)

SQL> select * from t2;

        ID NAME
---------- --------------------------------------------------
         1 jy

SQL> select * from t2;

        ID NAME
---------- --------------------------------------------------
         1 hy

SQL> select * from t2;

no rows selected

SQL> 
SQL> 
SQL> desc t3;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER(20)
 NAME                                               VARCHAR2(20)

SQL> select * from t3;

        ID NAME
---------- --------------------------------------------------
         1 jy

验证物理备库是否执行正确
在创建物理备库后并且设置重做传输服务,可能想要验证主库的数据库修改是否会成功的传输到备库。对于备库可以查询v$managed_standby视图来验证重做是否被从主库传输到备库并应用。

SQL> select client_process,process,thread#,sequence#,status from v$managed_standby where client_process='LGWR' or process='MRP0';

CLIENT_P PROCESS      THREAD#  SEQUENCE# STATUS
-------- --------- ---------- ---------- ------------
LGWR     RFS                1          9 IDLE
N/A      MRP0               1          9 APPLYING_LOG

上面的查询对于使用CLIENT_PROCESS为LGWR的主库会显示一行记录,它指示重做传输工作正常并且主重做线程将会被发送到备库。 如果主库是RAC数据库,那么对于使用CLIENT_PROCESS为LGWR的当前活动的每个主库实例都会显示一行记录。

上面的查询对于MRP也行显示一行。如果MRP的状态显示为APPLYING_LOG并且SEQUENCE#等于主库当前正被发送的日志序列号,那么备库已经解决了所有的日志差异并且当前处于实时应用日志模式。

查询主库当前正被发送日志的序列号为9与上面的MRP进程所显示的sequence#(9)相同

SQL> select group#,thread#,sequence#,status from v$log;

    GROUP#    THREAD#  SEQUENCE# STATUS
---------- ---------- ---------- ----------------
         1          1          7 INACTIVE
         2          1          8 INACTIVE
         3          1          9 CURRENT

注意MRP进程可能显示的sequence#比主库当前被发送的日志序列号小,那么这就表示正在应用的归档重做日志文件与发送的日志文件之间存在差异并且它并没有赶上。一旦所有差异被解决,相同的查询将显示MRP正在应用当前sequence#。

openPower服务器安装Oracle 19c

在openPower服务器上安装Oracle 19C
1.创建用户与组
1.1.创建组(在各个主机上执行)

mkgroup -'A' id='501' adms='root' oinstall
mkgroup -'A' id='502' adms='root' asmdba
mkgroup -'A' id='503' adms='root' asmoper
mkgroup -'A' id='504' adms='root' dba
mkgroup -'A' id='505' adms='root' oper
mkgroup -'A' id='506' adms='root' backdba
mkgroup -'A' id='507' adms='root' dgdba
mkgroup -'A' id='508' adms='root' racdba
mkgroup -'A' id='509' adms='root' kmdba

1.2.创建用户(在各个主机上执行)

mkuser id=601 pgrp=oinstall groups=dba,asmdba,oper,asmoper,backdba,dgdba,racdba,kmdba home=/home/oracle oracle

创建安装目录

mkdir -p /u01/app/oraInventory
mkdir -p /u01/app/oracle/product/19.3/db
mkdir -p /u01/temp

chown -R oracle:oinstall /u01
chmod -R 775 /u01

2.设置用户环境变量(用oracle用户来编辑.profile)

umask 022
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=/u01/app/oracle/product/19.3/db
export ORACLE_SID=hxsy
export ORACLE_UNQNAME=hxsy
export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
export NLS_DATE_FORMAT="yyyy-mm-dd hh24:mi:ss"
export PATH=.:${PATH}:$HOME/bin:$ORACLE_HOME/bin
export PATH=${PATH}:/usr/bin:/bin:/usr/bin/X11:/usr/local/bin
export PATH=${PATH}:$ORACLE_BASE/common/oracle/bin
export ORACLE_PATH=${PATH}:$ORACLE_BASE/common/oracle/sql:.:$ORACLE_HOME/rdbms/admin
export ORACLE_TERM=xterm
export TNS_ADMIN=$ORACLE_HOME/network/admin
export LD_LIBRARY_PATH=$ORACLE_HOME/lib
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:$ORACLE_HOME/oracm/lib
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/lib:/usr/lib:/usr/local/lib
export CLASSPATH=$ORACLE_HOME/JRE
export CLASSPATH=${CLASSPATH}:$ORACLE_HOME/jlib
export CLASSPATH=${CLASSPATH}:$ORACLE_HOME/rdbms/jlib
export CLASSPATH=${CLASSPATH}:$ORACLE_HOME/network/jlib
export THREADS_FLAG=native
export TEMP=/u01/tmp
export TMPDIR=/u01/tmp
export PS1=`hostname`:'$PWD'"$"

3.使用如下命令查看虚拟内存管理参数

vmo -L minperm%
vmo -L maxperm%
vmo -L maxclient%
vmo -L lru_file_repage
vmo -L strict_maxclient
vmo -L strict_maxperm

4.如果设置不合适,使用如下命令修改:

vmo -p -o minperm%=3
vmo -p -o maxperm%=90
vmo -p -o maxclient%=90
vmo -p -o lru_file_repage=0
vmo -p -o strict_maxclient=1
vmo -p -o strict_maxperm=0

5.检查网络参数设置
ephemeral参数:
5.1 使用命令no -a |fgrep ephemeral可以查看当前系统ephemeral参数设置,建议的参数设置如下

tcp_ephemeral_high = 65500
tcp_ephemeral_low = 9000
udp_ephemeral_high= 65500
udp_ephemeral_low = 9000

如果系统中参数设置和上述值不一样,使用命令修改:

#no -p -o tcp_ephemeral_low=9000 -o tcp_ephemeral_high=65500
#no -p -o udp_ephemeral_low=9000 -o udp_ephemeral_high=65500

使用如下命令修改网络可调整参数:

#no -p -o rfc1323=1
#no -r -o ipqmaxlen=512
#no -p -o ipqmaxlen=512
#no -p -o sb_max=4194304
#no -p -o tcp_recvspace=65536
#no -p -o tcp_sendspace=65536
#no -p -o udp_recvspace=1351680 该值是udp_sendspace的10倍,但须小于sb_max
#no -p -o udp_sendspace=135168

备注:-r表示reboot后生效,-p表示即刻生效.
检查内核参数maxuproc(建议16384)和ncargs(至少128)

#lsattr -E -l sys0 -a ncargs
#lsattr -E -l sys0 -a maxuproc

如果设置不合适使用如下命令修改:

#chdev -l sys0 -a ncargs=256
#chdev -l sys0 -a maxuproc=16384

6.解压数据库软件

aix1:/u01/soft$unzip -q AIX.PPC64_193000_db_home.zip -d $ORACLE_HOME

7.安装数据库软件
在$ORACLE_HOME/install/response目录中有一个安装rsp文件示例
7.1.配置响应文件

[oracle@ora19c ~]$ vi 19c_dbinstall.rsp
oracle.install.responseFileVersion=/oracle/install/rspfmt_dbinstall_response_schema_v19.0.0
oracle.install.option=INSTALL_DB_SWONLY
UNIX_GROUP_NAME=oinstall
INVENTORY_LOCATION=/u01/app/oraInventory
ORACLE_BASE=/u01/app/oracle
ORACLE_HOME=/u01/app/oracle/product/19.3/db
oracle.install.db.InstallEdition=EE
oracle.install.db.OSDBA_GROUP=dba
oracle.install.db.OSOPER_GROUP=oper
oracle.install.db.OSBACKUPDBA_GROUP=backdba
oracle.install.db.OSDGDBA_GROUP=dgdba
oracle.install.db.OSKMDBA_GROUP=kmdba
oracle.install.db.OSRACDBA_GROUP=racdba
oracle.install.db.rootconfig.executeRootScript=true
oracle.install.db.rootconfig.configMethod=ROOT

8.执行安装

openaix1:/home/oracle$$ORACLE_HOME/runInstaller -silent  -force -noconfig  -ignorePrereq  -responseFile /home/oracle/19c_dbinstall.rsp

********************************************************************************

Your platform requires the root user to perform certain pre-installation
OS preparation.  The root user should run the shell script 'rootpre.sh' before
you proceed with Oracle installation. The rootpre.sh script can be found at:
/u01/app/oracle/product/19.3/db/clone/rootpre.sh

Answer 'y' if root has run 'rootpre.sh' so you can proceed with Oracle
installation.
Answer 'n' to abort installation and then ask root to run 'rootpre.sh'.

********************************************************************************

Has 'rootpre.sh' been run by root in this machine? [y/n] (n)
y
Launching Oracle Database Setup Wizard...


 Enter password for 'root' user:
[WARNING] [INS-13014] Target environment does not meet some optional requirements.
   CAUSE: Some of the optional prerequisites are not met. See logs for details. installActions2020-11-17_01-49-09AM.log
   ACTION: Identify the list of failed prerequisite checks from the log: installActions2020-11-17_01-49-09AM.log. Then either from the log file or from installation manual find the appropriate configuration to meet the prerequisites and fix it manually.
The response file for this session can be found at:
 /u01/app/oracle/product/19.3/db/install/response/db_2020-11-17_01-49-09AM.rsp

You can find the log of this install session at:
 /u01/tmp/InstallActions2020-11-17_01-49-09AM/installActions2020-11-17_01-49-09AM.log
Successfully Setup Software with warning(s).
Moved the install session logs to:
 /u01/app/oraInventory/logs/InstallActions2020-11-17_01-49-09AM

9.配置监听
创建配置监听的响应文件
在/u01/app/oracle/product/19.3/db/assistants/netca/目录有一个示例文件

aix1:/home/oracle$vi 19c_netca.rsp
"19c_netca.rsp" [New file]

[GENERAL]
RESPONSEFILE_VERSION="19.0"
CREATE_TYPE="CUSTOM"

[oracle.net.ca]
INSTALLED_COMPONENTS={"server","net8","javavm"}
INSTALL_TYPE=""typical""
LISTENER_NUMBER=1
LISTENER_NAMES={"LISTENER"}
LISTENER_PROTOCOLS={"TCP;1521"}
LISTENER_START=""LISTENER""
NAMING_METHODS={"TNSNAMES","ONAMES","HOSTNAME"}
NSN_NUMBER=1
NSN_NAMES={"EXTPROC_CONNECTION_DATA"}
NSN_SERVICE={"PLSExtProc"}
NSN_PROTOCOLS={"TCP;HOSTNAME;1521"}


aix1:/home/oracle$netca /silent /responsefile /home/oracle/19c_netca.rsp
UnsatisfiedLinkError exception loading native library: njni19
java.lang.UnsatisfiedLinkError: njni19 (Not found in java.library.path)
java.lang.UnsatisfiedLinkError: oracle/net/common/NetGetEnv.jniGetOracleHome()Ljava/lang/String;
        at oracle.net.common.NetGetEnv.getOracleHome(Unknown Source)
        at oracle.net.ca.NetCALogger.getOracleHome(NetCALogger.java:230)
        at oracle.net.ca.NetCALogger.initOracleParameters(NetCALogger.java:215)
        at oracle.net.ca.NetCALogger.initLogger(NetCALogger.java:130)
        at oracle.net.ca.NetCA.main(NetCA.java:459)

Error: oracle/net/common/NetGetEnv.jniGetOracleHome()Ljava/lang/String;
Oracle Net Services configuration failed.  The exit code is 1


# lsdev | grep iocp
iocp0      Defined         I/O Completion Ports
# smitty iocp

# lsdev | grep iocp
iocp0      Available       I/O Completion Ports


aix1:/home/oracle$$ORACLE_HOME/bin/relink all
writing relink log to: /u01/app/oracle/product/19.3/db/install/relinkActions2020-11-16_11-17-27PM.log

aix1:/home/oracle$netca /silent /responsefile /home/oracle/19c_netca.rsp

Parsing command line arguments:
    Parameter "silent" = true
    Parameter "responsefile" = /home/oracle/19c_netca.rsp
Done parsing command line arguments.
Oracle Net Services Configuration:
Profile configuration complete.
Oracle Net Listener Startup:
    Running Listener Control:
      /u01/app/oracle/product/19.3/db/bin/lsnrctl start LISTENER
    Listener Control complete.
    Listener started successfully.
Listener configuration complete.
Oracle Net Services configuration successful. The exit code is 0

aix1:/home/oracle$lsnrctl status

LSNRCTL for IBM/AIX RISC System/6000: Version 19.0.0.0.0 - Production on 16-NOV-2020 23:24:53

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

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=aix1)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for IBM/AIX RISC System/6000: Version 19.0.0.0.0 - Production
Start Date                16-NOV-2020 23:23:28
Uptime                    0 days 0 hr. 1 min. 27 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /u01/app/oracle/product/19.3/db/network/admin/listener.ora
Listener Log File         /u01/app/oracle/diag/tnslsnr/aix1/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=aix1)(PORT=1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
The listener supports no services
The command completed successfully



10.创建数据库
10.1 创建配置数据库的响应文件
在/u01/app/oracle/product/19.3/db/assistants/dbca/目录中有一个示例文件

[oracle@ora19c install]$ cat /u01/app/oracle/product/19.3/db/assistants/dbca/dbca.rsp


aix1:/home/oracle$vi 19c_dbca.rsp
automaticMemoryManagement=TRUE
responseFileVersion=/oracle/assistants/rspfmt_dbca_response_schema_v19.0.0
templateName=General_Purpose.dbc
gdbName=hxsy
sid=hxsy
databaseConfigType=SI
createAsContainerDatabase=TRUE
numberOfPDBs=1
pdbName=hxsy1
useLocalUndoForPDBs=TRUE
pdbAdminPassword=hxsy_123456
sysPassword=hxsy_123456
systemPassword=hxsy_123456
storageType=FS
characterSet=ZHS16GBK
nationalCharacterSet=AL16UTF16
listeners=LISTENER
sampleSchema=TRUE
totalMemory 2048
databaseType=MULTIPURPOSE
automaticMemoryManagement=FALSE
totalMemory=4096

11.创建数据库

aix1:/home/oracle$dbca -silent  -createDatabase -responseFile /home/oracle/19c_dbca.rsp
[WARNING] [DBT-06208] The 'SYS' password entered does not conform to the Oracle recommended standards.
   CAUSE:
a. Oracle recommends that the password entered should be at least 8 characters in length, contain at least 1 uppercase character, 1 lower case character and 1 digit [0-9].
b.The password entered is a keyword that Oracle does not recommend to be used as password
   ACTION: Specify a strong password. If required refer Oracle documentation for guidelines.
[WARNING] [DBT-06208] The 'SYSTEM' password entered does not conform to the Oracle recommended standards.
   CAUSE:
a. Oracle recommends that the password entered should be at least 8 characters in length, contain at least 1 uppercase character, 1 lower case character and 1 digit [0-9].
b.The password entered is a keyword that Oracle does not recommend to be used as password
   ACTION: Specify a strong password. If required refer Oracle documentation for guidelines.
[WARNING] [DBT-06208] The 'PDBADMIN' password entered does not conform to the Oracle recommended standards.
   CAUSE:
a. Oracle recommends that the password entered should be at least 8 characters in length, contain at least 1 uppercase character, 1 lower case character and 1 digit [0-9].
b.The password entered is a keyword that Oracle does not recommend to be used as password
   ACTION: Specify a strong password. If required refer Oracle documentation for guidelines.
Prepare for db operation
8% complete
Copying database files
31% complete
Creating and starting Oracle instance
32% complete
36% complete
40% complete
43% complete
46% complete
Completing Database Creation
51% complete
53% complete
54% complete
Creating Pluggable Databases
58% complete
77% complete
Executing Post Configuration Actions
100% complete
Database creation complete. For details check the logfiles at:
 /u01/app/oracle/cfgtoollogs/dbca/hxsy.
Database Information:
Global Database Name:hxsy
System Identifier(SID):hxsy
Look at the log file "/u01/app/oracle/cfgtoollogs/dbca/hxsy/hxsy.log" for further details.

12.验证是否可以登录数据库

aix1:/u01/app/oracle/product/19.3/db/dbs$sqlplus / as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Mon Nov 16 16:32:33 2020
Version 19.3.0.0.0

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

Connected to an idle instance.

SQL> startup mount
ORACLE instance started.

Total System Global Area 3221222936 bytes
Fixed Size                  9303576 bytes
Variable Size             956301312 bytes
Database Buffers         2231369728 bytes
Redo Buffers               24248320 bytes
Database mounted.

SQL> alter database open;

Database altered.

SQL> show pdbs;

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 HXSY1                          MOUNTED

SQL> alter pluggable database hxsy1 open;

Pluggable database altered.

SQL> show pdbs;

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 HXSY1                          READ WRITE NO