Oracle 在12c 以后的版本引入了多租户的概念,关于架构和多租户的信息参考我之前的博客和书籍:
Oracle 12.2 家族的补丁 RU 和 RUR 说明
https://www.cndba.cn/dave/article/4063
《Oracle 18c 必须掌握的新特性》
https://www.cndba.cn/dave/article/3453
在多租户的架构中,我们实际使用的业务库并非CDB,而是PDB。
1 访问PDB 方法1: TNS
常规要访问PDB的库,我们都是需要配置TNS来解决,否则直接连接就访问到CDB。
[dave@www.cndba.cn ~]$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on Fri Apr 7 22:03:46 2023
Version 19.18.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.18.0.0.0
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 DAVE READ WRITE NO
SQL>
我们这里的PDB 名称叫DAVE,当然,我们可以在sqlplus 切换容器来访问PDB:
SQL> alter session set container=dave;
Session altered.
SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
3 DAVE READ WRITE NO
SQL>
但这种方式只能给DBA 使用,如果是给业务使用,这种方式就不透明了。 因此需要配置TNS来解决。
修改监听和TNS:
[dave@www.cndba.cn admin]$ cat listener.ora
# listener.ora Network Configuration File: /u01/app/oracle/product/19.3.0/dbhome_1/network/admin/listener.ora
# Generated by Oracle configuration tools.
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = cndba)
(ORACLE_HOME = /u01/app/oracle/product/19.3.0/dbhome_1)
(SID_NAME = cndba)
)
(SID_DESC =
(GLOBAL_DBNAME = dave)
(ORACLE_HOME = /u01/app/oracle/product/19.3.0/dbhome_1)
(SID_NAME = cndba)
)
)
LISTENER =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = oracle)(PORT = 1521))
)
ADR_BASE_LISTENER = /u01/app/oracle
[dave@www.cndba.cn admin]$ cat tnsnames.ora
# tnsnames.ora Network Configuration File: /u01/app/oracle/product/19.3.0/dbhome_1/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.
DAVE =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = dave)
)
)
[dave@www.cndba.cn admin]$
然后使用TNS连接PDB:
[dave@www.cndba.cn admin]$ sqlplus dave/dave@dave
SQL*Plus: Release 19.0.0.0.0 - Production on Fri Apr 7 22:14:09 2023
Version 19.18.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
Last Successful login time: Fri Apr 07 2023 22:13:11 +08:00
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.18.0.0.0
SQL> show con_name
CON_NAME
------------------------------
DAVE
SQL>
同样,在执行导出这样的任务时,也是使用TNS 来连接PDB 进行操作:
[dave@www.cndba.cn admin]$ expdp dave/dave@dave TABLES=employees directory=DUMP_DIR DUMPFILE= pdbtable.dmp LOGFILE= pdbtable.log
2 访问PDB 方法2:ORACLE_PDB_SID
第一种方式相对11g 直接连接实例来说,还是要麻烦一些的。 因此,我们可以使用第二种方法,直接连接PDB。 设置环境变量:ORACLE_PDB_SID,但是这种方法是有限制条件的。
How To Connect to PDB By OS Authentication In 19c Container Database Environment (Doc ID 2729416.1)
Because there is no bequeath connection available in PDB, it cannot connect to PDB directly by OS authentication.
But through logon trigger SYS or other external user can connect to PDB without password.
MOS 提到2点限制条件:
- 这种方式,只适用于Oracle 19.3 之后的版本,之前版本并不适用。
- SYS 和 非SYS 用户操作有区别。
2.1 SYS 用户
对于SYS 用户,可以直接通过预定义的触发器DBMS_SET_PDB 和 ORACLE_PDB_SID 环境变量来直接连接PDB,并且不需要输入密码。
[dave@www.cndba.cn admin]$ export ORACLE_PDB_SID=DAVE
[dave@www.cndba.cn admin]$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on Fri Apr 7 22:26:00 2023
Version 19.18.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.18.0.0.0
SQL> show con_name
CON_NAME
------------------------------
DAVE
SQL> quit
Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.18.0.0.0
[dave@www.cndba.cn admin]$ unset ORACLE_PDB_SID
[dave@www.cndba.cn admin]$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on Fri Apr 7 22:26:20 2023
Version 19.18.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.18.0.0.0
SQL> show con_name
CON_NAME
------------------------------
CDB$ROOT
SQL>
2.2 非SYS 用户
对于非SYS用户,则需要重新创建触发器:SET_PDB和环境变量ORACLE_PDB 来免密连接PDB。
--Modify initial parameter os_authent_prefix to the same value of common_user_prefix
[dave@www.cndba.cn admin]$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on Fri Apr 7 22:33:30 2023
Version 19.18.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.18.0.0.0
SQL> show parameter os_authent_prefix
NAME TYPE
------------------------------------ ---------------------------------
VALUE
------------------------------
os_authent_prefix string
ops$
SQL> alter system set os_authent_prefix='C##' scope=spfile;
System altered.
SQL>
--Create common user and grant necessary privilege, e.g create session,set container, etc.
create user c##<OS_USER_NAME> identified externally container=all;
grant create session,set container,<Other Privilege> to c##<OS_USER_NAME>;
SQL> create user c##oracle identified externally container=all;
User created.
SQL> grant create session,set container to c##oracle;
Grant succeeded.
----Restartup database
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
Total System Global Area 2399141320 bytes
Fixed Size 9166280 bytes
Variable Size 855638016 bytes
Database Buffers 1526726656 bytes
Redo Buffers 7610368 bytes
Database mounted.
Database opened.
SQL>
--Create logon trigger for this common user.
SQL> CREATE OR REPLACE TRIGGER SYS.set_pdb
2 AFTER LOGON ON DATABASE
3 WHEN (USER like '&USERNAME')
4 DECLARE
5 pdb_name varchar(64);
6 BEGIN
7 sys.DBMS_SYSTEM.get_env('ORACLE_PDB',pdb_name);
8 if(pdb_name is not null) then
9 EXECUTE IMMEDIATE 'alter session set container='||'"'||pdb_name||'"';
10 end if;
11 EXCEPTION when others then
12 null;
13 END set_pdb;
14 /
Enter value for username: C##ORACLE
old 3: WHEN (USER like '&USERNAME')
new 3: WHEN (USER like 'C##ORACLE') --注意这用户名要大写
Trigger created.
--sqlnet.ora:
[dave@www.cndba.cn admin]$ cat sqlnet.ora
SQLNET.AUTHENTICATION_SERVICES = (ALL)
[dave@www.cndba.cn admin]$
--Connect test
[dave@www.cndba.cn admin]$ export ORACLE_PDB=DAVE
[dave@www.cndba.cn admin]$ sqlplus /
SQL*Plus: Release 19.0.0.0.0 - Production on Fri Apr 7 22:49:45 2023
Version 19.18.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
Last Successful login time: Fri Apr 07 2023 22:48:57 +08:00
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.18.0.0.0
SQL> show con_name
CON_NAME
------------------------------
DAVE
SQL> show user;
USER is "C##ORACLE"
SQL>
版权声明:本文为博主原创文章,未经博主允许不得转载。