客服微信
本文为云贝教育 刘峰 原创,请尊重知识产权,转发请注明出处,不接受任何抄袭、演绎和未经注明出处的转载。
代理PDB可以提供引用远程PDB的本地连接点。在一些情况下,你可能会对此感兴趣。
您希望将PDB重新定位到不同的机器或数据中心,而不必更改任何现有的连接细节。在这种情况下,您可以重新定位PDB,并在原始位置创建同名的代理PDB。
您希望在云中运行PDB,但不希望开放对多个应用程序的访问,让每个应用程序都直接连接。相反,您让所有应用程序连接到本地PDB,而本地PDB又连接到引用的PDB,因此只有一条路由进出云PDB。
您希望在多个数据库之间共享单个应用程序根容器。
这里有一些需要考虑的事情。
从12.2开始,我们可以在单个CDB中拥有代理PDB、应用程序根容器和单个用户定义的PDB(常规或应用程序PDB),而无需支付多租户选项。注意,我们仍然仅限于一个用户定义的PDB。
创建代理PDB的先决条件与热克隆的先决条件类似,请参考热克隆章节。
在下面的示例中,我有两个数据库运行在同一个虚拟机上,但它们可以运行在单独的物理或虚拟服务器上。
cdb1:最终将容纳代理PDB的本地数据库。
cdb3:远程CDB,包含远程引用的PDB (pdb5)。
数据库使用Oracle管理文件(OMF),所以我不需要担心 FILE_NAME_CONVERT 或 PDB_FILE_NAME_CONVERT 设置。
代理PDB和被引用的PDB共享相同的侦听器,因此它们不能具有相同的名称。如果它们有不同的侦听器,无论是在同一台机器上还是在不同的机器上,它们都可以具有相同的名称。
注意事项:
1、远端的主机名需要在本地/etc/hosts中配置
2、连接远端的端口号默认是1521
连接到本地实例的根容器(cdb1)。具备先决条件后,我们可以使用以下命令创建并打开代理PDB。
CONN sys@cdb1 AS SYSDBA CREATE PLUGGABLE DATABASE pdb5_proxy AS PROXY FROM pdb5@clone_link; ALTER PLUGGABLE DATABASE pdb5_proxy OPEN;
如果您使用操作系统身份验证连接到根容器,切换到代理 PDB 容器并尝试执行查询,您将收到以下错误。
CONN / AS SYSDBA ALTER SESSION SET CONTAINER = pdb5_proxy; SQL> SELECT name FROM v$database; SELECT name FROM v$database * ERROR at line 1: ORA-01017: invalid username/password; logon denied ORA-02063: preceding line from PROXYPDB$DBLINK
如果您使用服务连接到 SYS,则交换机可以正常工作。
CONN sys@cdb1 AS SYSDBA ALTER SESSION SET CONTAINER = pdb5_proxy; SELECT name FROM v$database; NAME --------- CDB3
切换到PROXY PDB
CONN sys@cdb1 AS SYSDBA ALTER SESSION SET CONTAINER = pdb5_proxy; SELECT name FROM v$database; NAME --------- CDB3 SQL>
在“tnsnames”中创建一个新条目。本地实例中的代理PDB的“ora”文件。
PDB5_PROXY = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 本地主机名或IP)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = pdb5_proxy) ) )
您现在可以直接连接到代理 PDB。请注意,在下面的输出中,数据库名称显示为 CDB3,即使我们连接到 cdb1 实例中的 pdb5_proxy 容器也是如此。
CONN sys@pdb5_proxy AS SYSDBA SELECT name FROM v$database; NAME --------- CDB3
创建代理 PDB 后,就不再需要数据库链接和链接用户。
CONN sys@cdb1 AS SYSDBA DROP DATABASE LINK clone_link; CONN sys@cdb3 AS SYSDBA DROP USER c##remote_clone_user CASCADE CONTAINER=ALL;
我们将通过在代理 PDB 和引用的 PDB 中进行更改来测试代理 PDB。首先,创建一个新表空间,并在新表空间中创建一个具有配额的测试用户。
CONN sys@pdb5_proxy AS SYSDBA CREATE TABLESPACE test_ts DATAFILE SIZE 1M AUTOEXTEND ON NEXT 1M; CREATE USER test IDENTIFIED BY test DEFAULT TABLESPACE test_ts QUOTA UNLIMITED ON test_ts; GRANT CREATE SESSION, CREATE TABLE TO test;
使用新创建的用户连接到引用的 PDB 并创建测试表。
CONN test/test@pdb5 CREATE TABLE t1 (id NUMBER); INSERT INTO t1 VALUES (1); COMMIT;
返回代理PDB并查询表。
#需要重新创建连接才能看到 CONN test/test@pdb5_proxy SELECT * FROM t1; ID ---------- 1
将另一条记录插入代理 PDB 中的表中。
CONN test/test@pdb5_proxy INSERT INTO t1 VALUES (2); COMMIT;
返回引用的PDB并查询表。
CONN test/test@pdb5 SELECT * FROM t1; ID ---------- 1 2
我们可以看到代理 PDB 和引用的 PDB 正在按预期工作。
看起来有点奇怪的是 SYSTEM、SYSAUX、TEMP 和 UNDO 表空间被复制到本地实例并保持同步。
所有其他表空间仅存在于引用的实例中。
如果我们查询代理 PDB 中的数据文件和临时文件,我们将显示引用的 PDB 的数据文件和临时文件。
请注意与 USERS 和 TEST_TS 表空间关联的数据文件。如果我们检查本地实例,我们会看到不同的模式。请注意,与 USERS 和 TEST_TS 表空间关联的数据文件不存在。
CONN sys@pdb5_proxy AS SYSDBA SET LINESIZE 100 SELECT name FROM v$datafile; NAME ---------------------------------------------------------------------------------------------------- /u02/app/oracle/oradata/cdb3/pdb5/system01.dbf /u02/app/oracle/oradata/cdb3/pdb5/sysaux01.dbf /u02/app/oracle/oradata/cdb3/pdb5/undotbs01.dbf /u02/app/oracle/oradata/cdb3/pdb5/users01.dbf /u02/app/oracle/oradata/CDB3/469D84C85D196311E0538738A8C0B97D/datafile/o1_mf_test_ts_d877rjoo_.dbf SQL> SELECT name FROM v$tempfile; NAME ---------------------------------------------------------------------------------------------------- /u02/app/oracle/oradata/cdb3/pdb5/temp01.dbf SQL>
如果我们检查本地实例,我们会看到不同的模式。请注意,与 USERS 和 TEST_TS 表空间关联的数据文件不存在。
CONN / AS SYSDBA SHOW PDBS CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 PDB1 READ WRITE NO 5 PDB5_PROXY READ WRITE NO SQL> SET LINESIZE 100 SELECT name FROM v$datafile WHERE con_id = 5; NAME ---------------------------------------------------------------------------------------------------- /u02/app/oracle/oradata/CDB1/469F256E1081028AE0538738A8C079C7/datafile/ o1_mf_system_d876rtd8_.dbf /u02/app/oracle/oradata/CDB1/469F256E1081028AE0538738A8C079C7/datafile/o1_mf_sysaux_d876rtd9_.dbf /u02/app/oracle/oradata/CDB1/469F256E1081028AE0538738A8C079C7/datafile/o1_mf_undotbs1_d876rtd9_.dbf SQL> SELECT name FROM v$tempfile WHERE con_id = 5; NAME ---------------------------------------------------------------------------------------------------- /u02/app/oracle/oradata/CDB1/469F256E1081028AE0538738A8C079C7/datafile/o1_mf_temp_d876rtdb_.dbf SQL>
CREATE PLUGGABLE DATABASE ... AS PROXY FROM 命令还可以包含 HOST 和 PORT 子句。
CREATE PLUGGABLE DATABASE pdb5_proxy AS PROXY FROM pdb5@clone_link PORT=1526 HOST='ol7-122.localdomain';
如果引用的 PDB 通过 1521 以外的端口访问,则应使用 PORT 子句。如果要使用远程服务器上的hostname 命令生成的其他名称来访问引用的 PDB,则应使用 HOST 子句,例如DNS 别名或SCAN。使用从引用的 PDB 发出的以下命令修改主机和端口。
CREATE PLUGGABLE DATABASE pdb5_proxy AS PROXY FROM pdb5@clone_link PORT=1526 HOST='ol7-122.localdomain';
更改后,必须重新创建指向引用的 PDB 的任何代理 PDB。
您可以使用 V$PDBS.PROXY_PDB 列或 CDB_PDBS.IS_PROXY_PDB 列查看哪些是代理 PDB。
COLUMN name FORMAT A30 SELECT name, proxy_pdb FROM v$pdbs; NAME PRO ------------------------------ --- PDB$SEED NO PDB1 NO PDB5_PROXY YES SQL> COLUMN pdb_name FORMAT A30 SELECT pdb_name, is_proxy_pdb FROM cdb_pdbs; PDB_NAME IS_ ------------------------------ --- PDB1 NO PDB$SEED NO PDB5_PROXY YES
V$PROXY_PDB_TARGETS 显示有关代理 PDB 使用的引用 PDB 的连接详细信息的信息。
COLUMN target_host FORMAT A20 COLUMN target_service FORMAT A32 COLUMN target_user FORMAT A20 SELECT con_id, target_port, target_host, target_service, target_user FROM v$proxy_pdb_targets; CON_ID TARGET_PORT TARGET_HOST TARGET_SERVICE TARGET_USER ---------- ----------- -------------------- -------------------------------- -------------------- 5 1521 my-server 469d84c85d196311e0538738a8c0b97d