Oracle多租户容器数据库的安装和使用
转自 https://www.cnblogs.com/muhai/p/16628054.html
oracle多租户容器数据库:Oracle Multitenant Container Database(CDB)
一、多租户架构
oracle体系结构链接:https://www.cnblogs.com/muhai/p/16333182.html
优点:可快速实现数据的迁移;整合数据库资源。缺点:当CDB出现故障后pdb都不能使用了
二、多租户容器数据库安装
非容器数据库安装连接:https://www.cnblogs.com/muhai/p/16498840.html,因为19c数据库软件已经安装这里就不再安装,直接从dbca创建数据库开始,其他安装步骤都是一样的,除了第四步和第六步。
在第四步修改实例名,选中“Create as Container database”
在第六步,先不选中“Enable archiving”,等生产数据的时候再打开
之后等待安装成功。
三、多租户容器数据库切换
1、查看实例名及实例进程信息
tail -l /etc/oratab; ps -ef|grep orcl;
2、实例切换
. oraenv; //之后输入orclcdb,. oraenv是读取oratab文件信息 export ORACLE_SID=orclcdb; //这个也可以切换实例,可以切换到orclcdb、chenmu等其他实例
查看cdb、pdb相关信息
sqlplus / sysdba; //管理员账号登录,登录的是cdb show con_name; //查看当前容器 select name,cdb,open_mode,con_id from v$database; //查看数据库是否是cdb数据库 show pdbs; //查看pdb信息,种子数据库状态只能是read only
3、从cdb切换到pdb
alter session set container=orclpdb; //从cdb切换到orclpdb show con_name; show pdbs; conn / as sysdba; //从pdb切换回cdb只需要连接sys用户即可,或者alter session set container=cdb$root;
sqlplus sys/oracle@172.25.100.137:1521/orclpdb as sysdba; //也可以在连接时指定orclpdb服务进入pdb show con_name;
四、多租户容器数据库的开启与关闭
1、cdb的开启与关闭,与非容器数据库(non-CDB)没有差别
alter session set container=cdb$root; //切换会话到cdb select instance_name,status from v$instance; //可以查看目前状态是open shutdown immediate; //关闭数据库 startup nomount; //启动到nomount状态 select instance_name,status from v$instance; alter database mount; select instance_name,status from v$instance; alter database open; select instance_name,status from v$instance;
2、pdb的开始与关闭
只能关到mounted状态,即open->mounted(PDB关闭时open_mode是mounted,开启时是READ WRITE,也可能是READ ONLY;status在pdb开启时是normal,在pdb刚创建时是new),开启和关闭的模式与non-CDB是不太一样的。
(1)pdb的开启
alter pluggable database open; //数据库的关闭使用alter ... open,在cdb环境要指定pdb名称 show pdbs; //在开启时open_mode是read write select pdb_id,pdb_name,status from cdb_pdbs; //在开启时status是normal alter database open; //在pdb环境可以使用这条语句打开数据库;也可以使用startup
(2)pdb的关闭
alter pluggable database close; //在cdb关闭pdb时要指定pdb的名字,即alter pluggable database orclpdb close show pdbs; //查看pdb的status select pdb_id,pdb_name,status from cdb_pdbs; //关闭之后这个表查看报错 shutdown immediate; //也可以用shutdown关闭pdb,前提是处于pdb环境
(3)保存PDB的打开模式
设置 save state来保存pdb最后的状态,下次cdb打开时pdb状态保持在pdb最后的状态。
a、保存pdb的打开模式(默认设置成保存pdb的打开模式),pdb是开启的,cdb重启之后pdb还是开启的
alter pluggable database orclpdb save state; select con_name,instance_name,state from dba_pdb_saved_states; //在open状态下设置save state才能查询出来
如果是保存所有pdb的状态就alter pluggable database all save state;如果是保存多个就是alter pluggable database orclpdb1,orclpdb2 save state;discard同理 ,如果不包括某个pdb就在all后面添加except。
shutdown immediate; //在orclcdb下关闭和重启 startup; show pdbs; //最后pdb还是开启的
b、丢弃pdb的打开模式
alter pluggable database orclpdb discard state; select con_name,instance_name,state from dba_pdb_saved_states; show pdbs;
shutdown immediate; startup;
五、pdb容器的创建
控制文件、在线重做日志文件和参数文件,cdb和pdb是共用的;数据文件不共用,即system、sysaux、undotbs、users;创建pdb是cdb要存在并且是read write状态;当前用户是公共用户;拥有create pluggable database系统权限;选择唯一pdb名称。
1、从pdb$seed创建新的pdb(在另一台新主机172.25.100.2上实现,方便一会测试远程克隆pdb,克隆pdb到主机172.25.100.137)
在172.25.100.2上静默安装容器数据库,名字就是silent
dbca -silent -createDatabase -templateName General_Purpose.dbc -gdbName orclcdb -sid orclcdb -responseFile NO_VALUE -characterSet AL32UTF8 -emConfiguration NONE -createAsContainerDatabase true -useLocalUndoForPDBs true
安装成功之后,登录数据库通过pdb$seed创建可插拔数据库orclpdb2
create pluggable database orclpdb2 admin user admin identified by chen123 roles=(connect) file_name_convert=('/u01/app/oracle/oradata/ORCLCDB/pdbseed','/u01/app/oracle/oradata/ORCLCDB/orclpdb2') default tablespace users datafile '/u01/app/oracle/oradata/ORCLCDB/orclpdb2/users01.dbf' size 100M autoextend on; //在cdb中创建一个orclpdb2,赋予connect角色;不通过设置OMF即create_file_dest='u01/app/oracle/oradata'来放数据文件,而是通过设置file_name_convert; //因为pedseed没有user表空间,所以创建时指定,数据库打开后自动建立users表空间 col pdb_name for a16; select pdb_id, pdb_name, status from cdb_pdbs; //查看cdb里pdbs信息,刚创建的pdb状态是new
指定文件路径方式优先级file_name_convert>create_file_dest>db_create_file_dest>pdb_file_name_convert;属性Storage是指定pdb能用的最大容量;user_tablespaces指定PDB下使用哪些表空间;ROLES执行分配给admin用户的角色;
alter pluggable database orclpdb2 open; select pdb_id, pdb_name, status from cdb_pdbs; //状态从new变成normal
新建的pdb状态是new,open_mode是mount状态;第一次打开时只能以读写模式打开,不能以只读模式打开
alter session set container=orclpdb2; select name from v$datafile; //查看系统创建的数据文件
2、克隆本地PDB(在171.25.100.2上实现)
克隆PDB要先确认有没有创建可插拔数据库的权限;如果是本地主机不需要复制文件,指明文件位置即可(如果只要克隆orclpdb2的结构,不需要数据,可在from orclpdb2 后面加上NO DATA)
conn / as sysdba; //切换到根容器创建orclpdb3,从本地的orclpdb2上克隆,不需要从异地主机复制文件 create pluggable database orclpdb3 from orclpdb2 file_name_convert=('/u01/app/oracle/oradata/ORCLCDB/orclpdb2','/u01/app/oracle/oradata/ORCLCDB/orclpdb3') ; alter pluggable database orclpdb3 open;
与pdbseed不同的是不用指定admin user,但是要说明from orclpdb2
3、克隆远程PDB(从172.25.100.2上克隆orclpdb2到172.25.100.137)
在172.25.100.2源库上创建用于克隆pdb的公共用户并授权
create user c##remote identified by oracle container=all; //在172.25.100.2上创建用户并授权 grant create session,create pluggable database,create database link to c##remote container=all;
在目标库172.25.100.137创建连接指向源库172.25.100.2,并且创建orclpdb3
create database link pdb2_link connect to c##remote identified by oracle using '172.25.100.2:1521/orclpdb2'; //创建连接指向172.25.100.2 create pluggable database orclpdb3 from orclpdb2@pdb2_link file_name_convert=('/u01/app/oracle/oradata/ORCLCDB/orclpdb2','/u01/app/oracle/oradata/ORCLCDB/orclpdb3') ; //创建pdb并指定路径
4、克隆non-CDB库到CDB
前提条件是当前用户具有create pluggable database权限;源库处于read ony状态;源平台与目标平台拥有相同的字节序,选项保持一致或源是目标的子集,字符集和国家字符集要兼容;数据库版本在12.1.0.2以上。
有Data Pump(适合字节序不同、选项不一样且不是子集关系)、Plugging(最简便的方法)、Cloning(要求12C以上)、Replication四种方法。
startup open read only force; //现将chenmu实例调整成read only状态 exec dbms_pdb.describe('/tmp/CHENMU.xml'); //通过dbms_pdb.describe函数生成xml描述源数据库的架构 //在create pluggable database之前,确认两个数据库是否在同一个主机,如果在同一个主机就不用迁移数据,如果不在就要迁移数据到file_name_convert第一个路径位置 sqlplus / as sysdba; //登录多容器数据库的sys用户,有create pluggable database的权限 create pluggable database orclpdb4 using '/tmp/CHENMU.xml' file_name_convert=('/u01/app/oracle/oradata/CHENMU','/u01/app/oracle/oradata/ORCLCDB/orclpdb4');
alter pluggable database orclpdb4 open; //打开数据库显示出错 select time,name,cause,status from PDB_PLUG_IN_VIOLATIONS; //通过视图查看错误,显示Non-CDB to PDB,是因为源数据库是Non-CDB的架构,需要转成PDB的架构 set linesize 200; col time for a35; col name for a10; col cause for a25;
sqlplus /nolog; conn sys/oracle@172.25.100.137:1521/orclpdb4 as sysdba; @?/rdbms/admin/noncdb_to_pdb.sql; //执行non-CDB转换成PDB的脚本,大约需要30分钟 exit; sqlplus / as sysdba; alter pluggable database orclpdb4 close; alter pluggable database orclpdb4 open; //打开成功
5、可插拔PDB(从172.25.100.2拔下orclpdb2放到172.25.100.137)
前提是拥有相同的字节序,选项相同或源是目标的子集,字符集和国家字符集要兼容。
(1)源库先把pdb拔下来,以下在源库执行
ALTER PLUGGABLE DATABASE orclpdb2 close; ALTER PLUGGABLE DATABASE orclpdb2 UNPLUG INTO '/tmp/orclpdb2.xml'; //在根容器下执行 ho scp -r /tmp/orclpdb2.xml root@172.25.100.137:/tmp //将xml文件和数据文件传送到目标库172.25.100.137的/tmp下 ho scp -r /u01/app/oracle/oradata/ORCLCDB/orclpdb2 root@172.25.100.137:/tmp
(2)在目标库上检查兼容性
chown oracle:oinstall -R /tmp/orclpdb2.xml /tmp/orclpdb2; //在目标库根目录下将xml级orclpdb2下所有文件的所属用户改成oracle //在目标库cdb容器检查兼容性 SET SERVEROUTPUT ON DECLARE compatible CONSTANT VARCHAR2(3) := CASE DBMS_PDB.CHECK_PLUG_COMPATIBILITY( pdb_descr_file => '/tmp/orclpdb2.xml', pdb_name => 'orclpdb2') WHEN TRUE THEN 'YES' ELSE 'NO' END; BEGIN DBMS_OUTPUT.PUT_LINE(compatible); END; /
目标库上插入数据库,先查看/tmp/orclpdb2.xml文件的相关路径(/u01/app/oracle/oradata/ORCLCDB/orclpdb2),如果与172.25.100.2复制到的路径不一致(/tmp/orclpdb2),直接创建pdb会出现错误,因为创建时会到xml指定的路径找数据文件,复制到指定的路径,即找/u01/app/oracle/oradata/ORCLCDB/orclpdb2不存在,需要source_file_name_convert将两个地址转换,找/u01/app/oracle/oradata/ORCLCDB/orclpdb2就直接到/tmp/orclpdb2找,之后再创建。
CREATE PLUGGABLE DATABASE orclpdb2 USING '/tmp/orclpdb2.xml' source_file_name_convert=('/u01/app/oracle/oradata/ORCLCDB/orclpdb2','/tmp/orclpdb2') FILE_NAME_CONVERT = ('/tmp/orclpdb2', '/u01/app/oracle/oradata/ORCLCDB/orclpdb2');
6、使用DBCA静默克隆远程PDB(将172.25.100.2上的orclpdb2静默克隆到172.25.100.137上的orclpdb5)
条件:源库和目标库都要处于归档模式下,且源库的orclpdb2要处于开启状态;创建dblink的账号不能是sys
(1)在源库172.25.100.2上创建用于克隆pdb的公共用户并授权
create user c##remote identified by oracle container=all; //在172.25.100.2上创建用户并授权 grant create session,create pluggable database,create database link to c##remote container=all;
(2)静默建库
先打开源数据库orclpdb2
alter pluggable database orclpdb2 open; //打开orclpdb2不能正常开启,因为从源库把orclpdb2 unplug下来(在上面的第五步做了这一步),数据字典还是存在,再插上去先将数据库删除,但是不要删除数据文件 drop pluggable database orclpdb2; create pluggable database orclpdb2 using '/tmp/orclpdb2.xml' NOCOPY; show pdbs; alter pluggable database orclpdb2 open;
使用dbca静默克隆远程pdb,需要将源库和目标库的归档打开,否则会出现错误:Archive log mode is not enabled in the (orclpdb2) database.
shutdown immediate; startup mount; alter database archivelog; archive log list; alter database open;
alter pluggable database orclpdb2 open;
开始使用dbca静默安装
dbca -silent -createPluggableDatabase -createFromRemotePDB -remotePDBName orclpdb2 -remoteDBConnString 172.25.100.2:1521/orclpdb2 \
-remoteDBSYSDBAUserName sys -remoteDBSYSDBAUserPassword oracle -sysDBAUserName sys -sysDBAPassword oracle -dbLinkUsername c##remote \
-dbLinkUserPassword oracle -sourceDB orclcdb -pdbName orclpdb5 -pdbDatafileDestination /u01/app/oracle/oradata/ORCLCDB/orclpdb5
这里的remotePDBName远程PDB就是源数据库的pdb名称即orclpdb2;sourceDB就是本地的数据库即orclcdb;pdbDatafileDestination就是要创建的pdb路径
创建之后pdb是打开状态的。
六、创建应用程序容器(application container,即容器中的容器)
平时pdb都是创建在cdb下的,以cdb为根,但是application container是以pdb或pdbseed为根;优点是application root下存储的元数据和数据对所有的application pdb都是共享的。创建方法是先创建一个pdb作为application container的根(对标容器数据库的cdb),可以通过pdbseed来创建这个应用程序容器的根pdb;然后创建application seed(在创建application pdb时使用);最后再创建application pdb
1、创建application container(就是创建一个pdb,可以用上面的方法,就是要在名称后面加上as application container)
CREATE PLUGGABLE DATABASE approot AS APPLICATION CONTAINER ADMIN USER appadmin IDENTIFIED BY appadmin file_name_convert=('/u01/app/oracle/oradata/ORCLCDB/pdbseed','/u01/app/oracle/oradata/ORCLCDB/approot');
2、创建application seed(可根据application pdb、application root、pdb$seed来创建)
ALTER PLUGGABLE DATABASE APPROOT OPEN; //打开应用程序根容器 ALTER SESSION SET CONTAINER=APPROOT; //进入应用程序根容器 alter session set PDB_FILE_NAME_CONVERT = 'pdbseed','appseed'; CREATE PLUGGABLE DATABASE AS SEED ADMIN USER seedadmin IDENTIFIED BY seedadmin; //根据pdbseed来创建根容器的种子 show pdbs; //看到有个根容器及种子
ALTER PLUGGABLE DATABASE APPROOT$SEED OPEN; ALTER PLUGGABLE DATABASE CLOSE IMMEDIATE; ALTER PLUGGABLE DATABASE OPEN READ ONLY;
3、根据application seed创建application pdb(方法和根据pdbseed创建pdb一样)
alter session set container=approot; alter session set PDB_FILE_NAME_CONVERT = 'appseed','appcon1'; CREATE PLUGGABLE DATABASE appcon1 ADMIN USER appadmin IDENTIFIED BY appadmin;
4、application的安装
alter session set container=approot; ALTER PLUGGABLE DATABASE APPLICATION app_hr BEGIN INSTALL '1.0'; //安装应用app_hr CREATE TABLE ob SHARING=METADATA(a varchar(20)); //创建表且设置元数据是共享的 ALTER PLUGGABLE DATABASE APPLICATION app_hr END INSTALL '1.0'; //结束安装应用程序 select * from tab where tname='OB'; //查看OB表
七、容器数据库的使用
1、cdb创建用户及连接
公共用户是存在所有容器,但只能在根容器下创建公共用户,并且以c##为前缀开头,sys、system是系统预定义的公共用户不用加,可以查看公共用户前缀,能修改但是不建议修改。公共用户在不同容器的权限可能不同,
show parameter common_user;
create user chentest identified by chen123; //错误,在cdb中创建用户必须添加前缀名c## create user c##chentest identified by chen123; grant connect,resource to c##chentest; //授予登录权限 conn c##chentest/chen123; //连接用户,cdb可以本地连接,不用配tnsname文件和在后面加@...,监听程序监听的是cdb
2、pdb创建用户及连接
conn / as sysdba; //从sys用户切换cbd和pdb,c##chentest权限不足 alter session set container=orclpdb; //从orclcdb切换到orclpdb show con_name; select name,cdb,open_mode,con_id from v$database; create user chentest identified by chen123; //pdb创建用户和非容器数据库是一样的
pdb创建完用户并且授权之后连接该用户还是会报ORA-01017: invalid username/password; logon denied,原因是:oracle数据库默认监听的实例为cdb实例,需要进行修改tnsname文件
select name,network_name,pdb from v$services; //查看pdb的network_name vi tnsnames.ora; //在tns文件后面添加下面语句,host = chenmu这里的chenmu是主机名 orclpdb = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = chenmu)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = orclpdb) ) ) lsnrctl start; //修改tnsname.ora之后重启监听,否则会出现TNS:no listener sqlplus chentest/chen123@orclpdb //在密码后面添加@orclpdb,这里就是和cdb连接不同的地方 show con_name; //直接连接进pdb show user;
ps -ef| grep LOCAL; //pdb登录之后算是远程登录,后面带@的基本都是远程登录
八、删除pdb
drop pluggable database orclpdb2 including datafiles; //在orclcdb删除pdb,必须先关闭数据库 alter pluggable database orclpdb2 close immediate; drop pluggable database orclpdb2 including datafiles;