Oracle 18c 新特性:动态 Container Map 
增强 Application Container 灵活性
Oracle Application Container 的概念。
简单来说,在有了多租户的体系结构之后,很多 PDB 都可能共用同一套应用架构和元数据,所以 Oracle 在数据库中引入了应用容器的概念,
在应用容器中,首先存在一个 Application Root,可以在其中创建应用 SEED 数据库,种子数据库定义数据结构元数据等信息,然后其他和应用相关的数据库可以由此克隆而来,
加快部署,想一想这样的例子,如果在云上为100家客户部署收费系统,通过这样的Clone就很便捷。
在 Oracle 12.2 中增加的 Container Map 新特性,可以看做一个基于多租户 PDB 的 Sharding 架构,其基本原理是,如果我们在应用容器中构建一个分区表,
其分区可以映射到不同的PDB 中,而在整个应用容器中,数据结构逻辑上是一个整体,各 PDB 仅能操作自己分区的数据,而应用在全局则可以看到所有的数据。
在应用容器全局查询,可以透明的访问数据,而针对特定分区的数据访问会被自动路由到特定的 PDB 执行:
测试过程:
首先创建一个应用容器,这个 PDB 的名称是:apppdb1
 create pluggable database apppdb1 as application container admin user apppdb1 identified by apppdb1 file_name_convert=('/opt/oracle/oradata/ORCLCDB','/opt/oracle/oradata/ORCLAPP1');
接下来创建两个区域数据库,分别是 apppdb2 和 apppdb3:
create pluggable database apppdb2 admin user apppdb2 identified by apppdb2 file_name_convert=('/opt/oracle/oradata/ORCLCDB','/opt/oracle/oradata/ORCLAPP2');
create pluggable database apppdb3 admin user apppdb3 identified by apppdb3 file_name_convert=('/opt/oracle/oradata/ORCLCDB','/opt/oracle/oradata/ORCLAPP3');
接下来查看一下这几个数据库的角色,在 Application Root之下,是两个 Application PDB:
alter session set container=apppdb1;


SQL> alter session set container=APPPDB1;


Session altered.


SQL> create pluggable database apppdb2 admin user apppdb2 identified by apppdb2 file_name_convert=('/opt/oracle/oradata/ORCLCDB','/opt/oracle/oradata/ORCLAPP2');


Pluggable database created.


SQL> create pluggable database apppdb3 admin user apppdb3 identified by apppdb3 file_name_convert=('/opt/oracle/oradata/ORCLCDB','/opt/oracle/oradata/ORCLAPP3');


Pluggable database created.


SQL> select con_id,name,open_mode,application_root,application_pdb from v$pdbs;


    CON_ID NAME                           OPEN_MODE            APPLIC APPLIC
---------- ------------------------------ -------------------- ------ ------
         4 APPPDB1                        READ WRITE           YES    NO
         6 APPPDB2                        MOUNTED              NO     YES
         7 APPPDB3                        MOUNTED              NO     YES


SQL> alter pluggable database all open;


Pluggable database altered.


SQL> select con_id,name,open_mode,application_root,application_pdb from v$pdbs;


    CON_ID NAME                           OPEN_MODE            APPLIC APPLIC
---------- ------------------------------ -------------------- ------ ------
         4 APPPDB1                        READ WRITE           YES    NO
         6 APPPDB2                        READ WRITE           NO     YES
         7 APPPDB3                        READ WRITE           NO     YES


现在对应用容器进行初始化,在其中部署初始的元数据,创建 containermap ,然后创建数据表并对数据表启用 container_map ,最后完成这个应用元数据库的部署:
SQL> alter pluggable database application apppdb1 begin install '1.0';


SQL> create user siyang identified by siyang888;


User created.


SQL> grant dba to siyang;


SQL> create table siyang.containermap (CITY varchar2(20) not null)
  2  partition by list (city) (
  3  partition apppdb2 values('BEIJING'),
  4  partition apppdb3 values('CHENGDU'));


Table created.


SQL> ALTER PLUGGABLE DATABASE SET CONTAINER_MAP='siyang.containermap';


Pluggable database altered.


SQL> create table siyang.emp sharing=metadata (
  2  empno number,
  3  ename varchar2(20),
  4  city varchar2(20));


Table created.


SQL> alter table siyang.emp enable container_map;


Table altered.


SQL> alter table siyang.emp enable containers_default;


Table altered.


SQL> alter pluggable database application apppdb1 end install '1.0';


Pluggable database altered.
在应用PDB中,需要先刷新同步元数据,否则对象信息并不可见:


SQL> alter session set container=apppdb2;


Session altered.


SQL> alter pluggable database application apppdb1 sync;


Pluggable database altered.


SQL> desc siyang.emp;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 EMPNO                                              NUMBER
 ENAME                                              VARCHAR2(20)
 CITY                                               VARCHAR2(20)


SQL> insert into siyang.emp values(1,'SIYANG','BEIJING');


1 row created.


SQL> insert into siyang.emp values(1,'WK','BEIJING');


1 row created.


SQL> COMMIT;


Commit complete.


SQL> alter session set container=apppdb3;


Session altered.


SQL> desc siyang.emp
ERROR:
ORA-04043: object siyang.emp does not exist




SQL> alter pluggable database application apppdb1 sync;


Pluggable database altered.


SQL> desc siyang.emp
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 EMPNO                                              NUMBER
 ENAME                                              VARCHAR2(20)
 CITY                                               VARCHAR2(20)


SQL> insert into siyang.emp values(3,'WANGLEI','CHENGDU');


1 row created.


SQL> COMMIT;


Commit complete.


SQL> select * from siyang.emp;


     EMPNO ENAME
---------- ----------------------------------------
CITY
----------------------------------------
         3 WANGLEI
CHENGDU




SQL> alter session set container=apppdb2;


Session altered.


SQL> select * from siyang.emp;


     EMPNO ENAME
---------- ----------------------------------------
CITY
----------------------------------------
         1 SIYANG
BEIJING


         1 WK
BEIJING




SQL> alter session set container=apppdb1;


Session altered.


SQL> select * from siyang.emp;


     EMPNO ENAME
---------- ----------------------------------------
CITY                                         CON_ID
---------------------------------------- ----------
         1 SIYANG
BEIJING                                           6


         1 WK
BEIJING                                           6


         3 WANGLEI
CHENGDU                                           7










在容器数据库中分别插入数据,注意,在 apppdb2 的数据库中只能插入相关分区的数据,如果试图插入不存在的分区或其他MAP区域数据,会显示出错
注意我接下来切换到另外一个 PDB ,结果发现前面未提交的数据会对后续的操作形成阻塞,事实上这说明 alter session set container 这个 DDL 没有隐式提交之前的事务,必须切换回到原PDB下提交事务
在不同PDB只能查询和操作各自PDB的信息,而在Application Root 则可以查询全部数据
在 18c 增加的动态容器映射特性,允许我们增加、分拆分区数据,进一步的增强了灵活性。


create pluggable database s_asmer container_map update (add partition s_asmer values('XX','XX'));
create pluggable database s_asmer_peru container_map update(split partition s_asmer into (partition s_asmer ('XX'),partion s_asmer_pery));
09-01 05:05