创建
使用CREATE PLUGGABLE DATABASE 在CDB 中使用CDB 种子pdb$seed 创建PDB 。
使用CDB 种子(pdb$seed )创建PDB ,pdb$seed 只读模式,不可以修改!
在dbca 工具中创建root container :

勾选 Create as Container database ,勾选 Use Local Undo tablespace for PDBs ,选择 Create an empty Container database ,点击 Next 。
注:
Create as Container database – 12c 新特性,以容器模式创建数据库平台,随后可以创建 PDB ,或者将其他数据库以 PDB 的形式迁移到该平台;
Use Local Undo tablespace for PDBs , 12cR1 时 CDB 和所有的 PDB 公用 Undo 表空间, 12cR2 引入本地 Undo 表空间,每个 PDB 都可以有自己的 Undo 表空间。
在后续选择字符集的时候,强烈建议 CDB 与所有 PDB 的数据库字符集均保持一致 ( 也可以 CDB 根容器默认采用字符集 AL32UTF8 ,多租户是支持每一个 PDB 拥有不同的字符集 , 但是这种方法比较少见 ) 。
命令行创建与打开:
# su - oracle
$ sqlplus / as sysdba;
SQL> create pluggable database frankpdb admin user pdbadm identified by szfrank123p FILE_NAME_CONVERT=('/opt/oracle/backup','/opt/oracle/backup/frankpdb');
SQL> alter pluggable database frankpdb open instances=all;
SQL> alter pluggable database frankpdb save state instances=all;
为新创建的pdb 用户pdbadm 进行赋权:
# su - oracle
$ sqlplus / as sysdba;
SQL> alter session set container=frankpdb;
SQL> grant connect,resource to pdbadm;
SQL> 根据业务需要把其他权利赋予pdbadm
-- 测试连接
$ sqlplus pdbadm/szfrank123p@corebank1:1521/frankpdb
SQL> show user
USER is "PDBADM"
命令注解:
1: 创建的pdb 名字是frankpdb 。
2: 该pdb 的管理用户是pdbadm, 密码是szfrank123p, 该用户只存在于pdb 数据库frankpdb 中。
3: 设置新创建的pdb 的目录是file_name_convert=( 'PDB$SEED 的数据文件目录' , ' 新PDB 的数据文件目录' ); 本示例中, PDB$SEED 的数据文件目录 /opt/oracle/backup , 新PDB 的数据文件目录 /opt/oracle/backup/frankpdb
4 :open instances=all 表示在RAC 所有实例( 单实例就是自己) 上启动该pdb.
5: 通过SAVE STATE 保存CDB 重启前PDB 的状态。这样重启CDB 之后,会自动打开PDB 到之前的状态。
用这种方式创建PDB ,物理备库环境会自动创建对应的PDB 。
创建PDB 后,需要设置PDB 参数,控制PDB 内存资源的使用,主要内存配置参考如下:
注意:下面表格的参数值,只是 CDB 环境下多 PDB 配置演示,具体仍需要结合实际硬件环境
和业务对资源的需求来制定规范 ( 不同金融行业客户业务也不同 ) 。
|
PBD 参数/资源池名称 |
smallpool |
middlpool |
bigpool |
largepool |
selfpool |
|
sga_target ( 建议使用ASMM) |
4000m |
8000m |
16000m |
32000m |
N/A |
|
shared_pool_size |
1000m |
2000m |
4000m |
8000m |
N/A |
|
db_cache_size |
1000m |
2000m |
6000m |
12000m |
N/A |
|
pga_aggregate_limit |
2000m |
2000m |
4000m |
8000m |
N/A |
|
pga_aggregate_target |
600m |
1000m |
2000m |
4000m |
N/A |
|
sessions |
300 |
300 |
750 |
1000 |
N/A |
|
cpu_count |
1 |
2 |
4 |
8 |
N/A |
|
job_queue_processes |
256 |
256 |
256 |
256 |
N/A |
在CDB 级数据库中,要注意target_pdbs 参数的设置:
|
CDB 参数 |
建议值 |
|
target_pdbs |
默认算法:If this parameter is not set, then default value is calculated based on maximum SGA size for this CDB divided by 512MB per pdb.
建议值:规划几个pdb 就设置为几,例如在CDB 里规划了4 个PDB ,就设置为4.
-- 在 CDB 里修改示例: ( 这里的 4 只是举例 ) SQL> alter system set target_pdbs= 4 scope=spfile; -- 找割接窗口重启CDB 生效 |
|
_enable_shared_pool_durations |
之前在多 pdb 环境下经常出 ORA-4031 错误, shared pool 内存不足导致,该隐含参数修改为 false 以后, subheap 消失了,每个 subpool 只有一个 subheap 了,目前 Oracle 公有云也设置了该隐含参数,尽量避免 ORA-4031 错误出现的频率。
-- 建议在 CDB 里设置为 false : SQL> ALTER SYSTEM SET "_enable_shared_pool_durations"=false scope=spfile; -- 找割接窗口重启CDB 生效 |
其中,可以用下面的脚本检查所有可以在某个pdb 里修改的数据库参数:
set linesize 200
col name for a40
col value for a30
col DISPLAY_VALUE for a30
col default_value for a30
set colsep |
SELECT NAME,VALUE,DISPLAY_VALUE,default_value
FROM v$parameter
WHERE ISPDB_MODIFIABLE='TRUE'
order by name;
可以用下面的脚本检查某个参数在CDB 和所有PDB 里的参数设置值( 例如shared_pool_size) :
set linesize 200
col name for a40
col value for a30
set colsep |
SELECT CON_ID,NAME,VALUE
FROM v$system_parameter
WHERE NAME='shared_pool_size'
order by CON_ID;
参考文献:
Performance Issues when using PDBs with Oracle RAC 19c and 18c (Doc ID 2644243.1)
target_pdb parameter (Doc ID 2442274.1)
设置参数(PDB )
SQL> alter system set awr_pdb_autoflush_enabled=true;
设置快照属性(PDB)
SQL> exec dbms_workload_repository.modify_snapshot_settings(interval => 30);
备注:CDB 参数需要设置awr_snapshot_time_offset
(非必选项)
本章节的内容非必选项,例如在多个PDB 环境下,有的pdb 的定时作业窗口有特殊运行时间要求,比如需要在本PDB 内增加窗口来额外进行数据库统计信息多次收集,则需要增加数据库统计信息时间窗口,例如分别对应的时间是:6 点开始持续2 小时;12 点开始持续1 小时;18 点开始持续1 小时,演示执行命令如下: ( 此处是演示,非生产环境必选项 )
su - oracle
export ORACLE_SID=xxxx
sqlplus / as sysdba;
alter session set container=<pdbname>
select dbms_scheduler.stime from dual;
begin
dbms_auto_task_admin.disable(
client_name => 'auto optimizer stats collection',
operation => null,
window_name => null);
end;
/
begin
dbms_scheduler.create_window(
window_name => 'MORNING_WINDOW',
duration => numtodsinterval(2, 'hour'),
resource_plan => 'DEFAULT_MAINTENANCE_PLAN',
repeat_interval => 'FREQ=DAILY;BYHOUR=6;BYMINUTE=0;BYSECOND=0');
end;
/
begin
dbms_scheduler.add_group_member(
group_name => 'MAINTENANCE_WINDOW_GROUP',
member => 'MORNING_WINDOW');
end;
/
begin
dbms_scheduler.add_group_member(
group_name => 'ORA$AT_WGRP_OS',
member => 'MORNING_WINDOW');
end;
/
begin
dbms_scheduler.create_window(
window_name => 'MIDNOON_WINDOW',
duration => numtodsinterval(1, 'hour'),
resource_plan => 'DEFAULT_MAINTENANCE_PLAN',
repeat_interval => 'FREQ=DAILY;BYHOUR=12;BYMINUTE=0;BYSECOND=0');
end;
/
begin
dbms_scheduler.add_group_member(
group_name => 'MAINTENANCE_WINDOW_GROUP',
member => 'MIDNOON_WINDOW');
end;
/
begin
dbms_scheduler.add_group_member(
group_name => 'ORA$AT_WGRP_OS',
member => 'MIDNOON_WINDOW');
end;
/
begin
dbms_scheduler.create_window(
window_name => 'AFTERNOON_WINDOW',
duration => numtodsinterval(1, 'hour'),
resource_plan => 'DEFAULT_MAINTENANCE_PLAN',
repeat_interval => 'FREQ=DAILY;BYHOUR=18;BYMINUTE=0;BYSECOND=0');
end;
/
begin
dbms_scheduler.add_group_member(
group_name => 'MAINTENANCE_WINDOW_GROUP',
member => 'AFTERNOON_WINDOW');
END;
/
begin
dbms_scheduler.add_group_member(
group_name => 'ORA$AT_WGRP_OS',
member => 'AFTERNOON_WINDOW');
end;
/
BEGIN
dbms_auto_task_admin.enable(
client_name => 'auto optimizer stats collection',
operation => NULL,
window_name => NULL);
END;
/
select * from dba_autotask_window_clients;
execute dbms_scheduler.set_attribute('WEEKNIGHT_WINDOW','RESOURCE_PLAN','');
execute dbms_scheduler.set_attribute('WEEKEND_WINDOW','RESOURCE_PLAN','');
execute dbms_scheduler.set_attribute('SATURDAY_WINDOW','RESOURCE_PLAN','');
execute dbms_scheduler.set_attribute('SUNDAY_WINDOW','RESOURCE_PLAN','');
execute dbms_scheduler.set_attribute('MONDAY_WINDOW','RESOURCE_PLAN','');
execute dbms_scheduler.set_attribute('TUESDAY_WINDOW','RESOURCE_PLAN','');
execute dbms_scheduler.set_attribute('WEDNESDAY_WINDOW','RESOURCE_PLAN','');
execute dbms_scheduler.set_attribute('THURSDAY_WINDOW','RESOURCE_PLAN','');
execute dbms_scheduler.set_attribute('FRIDAY_WINDOW','RESOURCE_PLAN','');
-- 如果配置了1.4 节增加统计信息时间窗口则可以配置,否则请忽略下面三条配置
execute dbms_scheduler.set_attribute('AFTERNOON_WINDOW','RESOURCE_PLAN','');
execute dbms_scheduler.set_attribute('MIDNOON_WINDOW','RESOURCE_PLAN','');
execute dbms_scheduler.set_attribute('MORNING_WINDOW','RESOURCE_PLAN','');
在PDB 数据库里执行: ( 此处在 CDB 数据库里也同样建议禁用掉这两个 advisor, 只保留统计信息收集的 advisor)
exec dbms_auto_task_admin.disable('auto space advisor',null,null);
exec dbms_auto_task_admin.disable('sql tuning advisor',null,null);
在 CDB 级别和 PDB 级别,可以采用下面的 SQL 文本进行数据库的 advisor 是否允许运行 : (advisor 程序在 CDB 数据库和 PDB 数据库中分别存在 , 允许独自配置 )
set linesize 160 pagesize 1000
col CLIENT_NAME format a40
col CONSUMER_GROUP format a30
col WINDOW_GROUP format a30
select CON_ID,CLIENT_NAME,STATUS,CONSUMER_GROUP,WINDOW_GROUP
from cdb_autotask_client
order by con_id, client_name;
使用lockdown profile(非必选项)
注意:本章节对 PDB lockdown profile 功能进行使用演示,知道如何使用即可。
目前在生产环境配置中,使用 lockdown profile 限制仍然不多。
Oracle 12.2 开始引入的lockdown profile ,对于想给PDB 用户给比较大的权限,但是又想限制PDB 修改一些参数,能够影响CDB 的正常运行的参数。
下面进行具体示例:
1. 在CDB 级别创建profile
SQL> CREATE LOCKDOWN PROFILE dba_non_prof;
2. 设置profile 需要disable 的权限,此处禁止在pdb 里alter system:
SQL> ALTER LOCKDOWN PROFILE dba_non_prof DISABLE STATEMENT = ('ALTER SYSTEM');
3. 在CDB 级别设置pdb_lockdown profile 限制:
SQL> ALTER SYSTEM SET PDB_LOCKDOWN=dba_non_prof;
在pdb 里,再次执行alter system 则报出错误:
SQL> alter session set container=FRANKPDB;
Session altered.
SQL> alter system set shared_pool_size=100M scope=both;
alter system set shared_pool_size=100M scope=both
*
ERROR at line 1:
ORA-01031: insufficient privileges
我们可以使用DBA_LOCKDOWN_PROFILES 视图查询当前数据库中的lockdown profile 。
如果我们不想使用该profile ,也可以在CDB 级别删除。
SQL> drop lockdown profile dba_non_prof;
删除之后,在pdb 中则没有了’alter system’ 操作限制。
或者是在割接等特殊时期,在CDB 数据库里先不设置参数PDB_LOCKDOWN ,等正常营业之后再恢复参数PDB_LOCKDOWN 也可:( 该参数可以在CDB 里动态修改)
SQL> ALTER SYSTEM SET PDB_LOCKDOWN='';
官方文献:(lockdown profile 功能列表)
