docker 下配置 Oracle Database Server 12c R2
1、下载镜像
1)https://hub.docker.com/_/oracle-database-enterprise-edition
2)填写一些信息,命令行输入 docker login 登陆后下载镜像。
2、修改源(可选)
采用阿里云提供的国内源,Docker Desktop 依次进入 Settings→Docker Engine,在 registry-mirrors 属性下添加地址(仅供参考):
| 1 | { | 
3、执行镜像
以 win10 为例。根据文档 Oracle Database Server Docker Image Documentation(Oracle 数据库服务端 Docker 镜像文档)其中 Reusing existing database 小节内容,将本地 D:\oracledata 挂载到 /ORCL,参考命令行如下:
| 1 | docker run --name oracle -d -p 1521:1521 --restart=always -v D:/oracledata:/ORCL 12a359cd0528 | 
4、登录
使用 Docker Desktop 进入容器命令行,执行 source /home/oracle/.bashrc 激活环境变量,再执行 sqlplus /nolog,否则提示找不到命令。
或按照文档提示,直接执行
$ docker exec -it <Oracle-DB> bash -c "source /home/oracle/.bashrc; sqlplus /nolog",效果相同;或执行docker exec -it oracle /bin/bash进入正在运行容器的命令行,执行sqlplus / as sysdba登入,这种方式不用激活环境变量。
.bashrc 内容如下:
| 1 | # .bashrc | 
进入后连接至 SYS 账户 connect / as sysdba
5、修改密码(可选)
| 1 | alter user sys identified by oracle; | 
之后可在命令行输入 sqlplus,用上述用户登录即可
注:SYS 账户必需以 dba 权限登录,应输入用户名
sys as sysdba
6、CDB 和 PDB
Oracle 12c 引入了 CDB 与 PDB,在 ORACLE 12c 数据库引入的多租用户环境(Multitenant Environment)中,允许一个数据库容器(CDB)承载多个可插拔数据库(PDB)。CDB 全称为 Container Database,翻译为数据库容器,PDB 全称为 Pluggable Database,即可插拔数据库。在 ORACLE 12c 之前,实例与数据库是一对一或多对一关系(RAC),即一个实例只能与一个数据库相关联,数据库可以被多个实例所加载。而实例与数据库不可能是一对多的关系。当进入 ORACLE 12c 后,实例与数据库可以是一对多的关系。
CDB 相当于操作系统,调用并管理各个 PDB。PDB 相当于真正提供业务需求的数据库实例。ORACLE 12c 安装后只创建了 CBD,需要自己生成相应的 PDB。平时的数据库操作大多数和 PDB 相关。
注:数据库创建完成后默认带有一个名为 ORCLPDB1 的 PDB
相关命令:
- select name,open_mode from v$pdbs;用来查看当前 CDB 容器中包含的 PDB 容器
- show pdbs;查看全部目前的 PDB
- show con_name;查看当前所在是 CDB 还是 PDB
7、用户分类
Oracle 12c 的用户分为公共用户和本地用户
公共用户:可以为 CDB 管理员创建,公共用户是在所有的 PDB 中都可以使用的用户,公共用户的信息存在 CDB$ROOT 中,并且存在于所有的 PDB 中。公共用户需要连到 CDB 进行创建和管理。在 CDB 中创建的用户默认就是公共用户,可以省略 container=all,在 CDB 中只能创建公共用户,不能创建本地用户。
本地用户:本地用户只会存储在对应的 PDB 中,在 PDB 中创建的用户默认就是本地用户,可以省略 container=current,在 PDB 中只能创建本地用户,不能创建公共用户。
为了区分公共用和本地用户,引进了新的参数 common_user_perfix,表示公共用户的前缀,默认为 c##,也就是说如果创建了一个公共用户,必须带上前缀,如果不加 c##,则会提示错误 ORA-65096:公用用户名或角色名无效。此前缀是可以进行修改的,但是建议不要修改。执行以下命令查看前缀:
| 1 | show parameter common_user; | 
创建用户并授权
| 1 | create user C##test identified by 123456; | 
8、切换至 PDB
注意:使用这个命令需要的 sysdba 级别的权限,否则无法执行。切换后才可使用当前 PDB 的私有用户进行操作,12c 数据库创建完成后,默认情况下,使用 sqlplus / as sysdba 登录连接的是 CDB
执行 show con_name;,当前在 CDB 容器中
| 1 | CON_NAME | 
使用 show pdbs; 查询目前现有的 PDB 容器
| 1 | CON_ID CON_NAME OPEN MODE RESTRICTED | 
使用下列命令切换
| 1 | SQL> alter session set container=ORCLPDB1; | 
执行 show con_name; 验证:
| 1 | CON_NAME | 
说明切换成功,此时就可以创建本地用户并授权:
| 1 | SQL> create user test identified by 123456; | 
9、切换至 CDB
如果要切换回 CDB 容器只需将容器名换为 CDB 容器的名字即可,一个 CDB 只有一个根
| 1 | SQL> alter session set container=CDB$ROOT; | 
10、登陆或连接
使用 DataGrip 登录 PDB 使用 serviceName 登录,默认为实例名称后加 localdomain(例如 ORCLPDB1.localdomain),可通过 tnsnames.ora 查看。查找文件所在路径:
| 1 | find / -name tnsnames.ora | 
观察环境变量 export TNS_ADMIN=/u01/app/oracle/product/12.2.0/dbhome_1/admin/ORCLCDB 可知正确路径。从 ORCLCDB/tnsnames.ora 可看到 ORCLCDB 和 ORCLPDB 的 serviceName,或用命令查询当前可用 serviceName
| 1 | SQL> select name,pdb from v$services order by name; | 
11、查看用户
如果处在 CDB$ROOT 中查询 DBA 视图,那么只能查询到公共的数据字典;如果处在 PDB 中,那么查询 DBA 视图只能查到此 PDB 的数据字典。12c 中新增了 CDB 数据字典,可以查看所有的数据字典。所以,当在 CDB 中查询 dba_users,那你只能查询到公共的用户,当处于 PDB 中,只能查到 PDB 中的本地用户;如果想查询所有的用户,可以使用下的语句。其中新增 oracle_maintained 字段提示了此用户是否由 oracle 管理:
| 1 | SQL> select a.username,a.common,a.con_id,decode(a.CON_ID,1,'CDB$ROOT',b.pdb_name) name from cdb_users a,cdb_pdbs b | 
以此类推,公共用户修改密码只能在 CDB$ROOT 中进行修改;本地用户只能在 PDB 中进行修改:
| 1 | SQL> alter user c##cdb identified by newcdb; | 
12、删除用户
命令:drop user C##用户名
若用户拥有对象,则不能直接删除,否则将返回一个错误值。指定关键字 cascade,可删除用户所有的对象,然后再删除用户。
13、用户授权
创建一个公共用户,此时是没有任何登录权限的:
| 1 | SQL> create user c##cdb identified by cdb; | 
在 CDB 中赋予 c##cdb 登录权限后,就可以登录到 CDB。登录 sys 账户进行授权(登录时默认在 CDB 中):
| 1 | conn / as sysdba | 
注:grant 不添加 container 子句,则默认为当前容器,即
grant create session to c##cdb container=current;
配置权限后可成功切换用户:
| 1 | SQL> conn c##cdb/cdb | 
在 PDB 内部的授权为本地授权,可以在 PDB 中对公共用户进行授权。公共用户虽然在所有 PDB 中都存在,但并不是创建了公共用户就有权限访问所有 PDB,还需要单独赋予 create session 权限。此时还没有赋予单独的 PDB 权限给账户,当尝试连接其他 PDB 时会报错:
| 1 | SQL> alter session set container=ORCLPDB1; | 
通过登录 sys 账户连接 PDB,再对账户进行授权:
| 1 | SQL> conn / as sysdba | 
或者对公共用户进行公共授权,授权之后的用户就拥有了所有 PDB 的相关权限:
| 1 | SQL> grant create session to c##cdb container=all; | 
14、查看权限
| 1 | SQL> select * from dba_sys_privs where grantee like 'C##%'; | 
15、撤销权限
| 1 | SQL>revoke create table from test; | 
16、通过 pdbseed 新建 PDB
查找 pdbseed 目录的路径,例如 /u02/app/oracle/oradata/ORCL/pdbseed(可在挂载目录中查看),使用 sys 用户下执行下列命令:
| 1 | SQL> create pluggable database ORCLPDB2 admin user pdbadmin identified by oracle roles=(resource) file_name_convert=('/u02/app/oracle/oradata/ORCL/pdbseed','/u02/app/oracle/oradata/ORCL/orclpdb2'); | 
注 1:orclpdb2 目录不存在,执行后自行建立;注 2:要在 CBD 容器下下执行该命令
17、克隆本地 PDB 新建 PDB
被克隆的 PDB 模式要修改为 read only
| 1 | SQL> alter pluggable database ORCLPDB2 close; | 
18、更改 PDB 模式
| 1 | alter pluggable database ORCLPDB2 open read write; | 
登陆时提示错误
| 1 | ERROR: | 
注意用户是否授权,另外要增加连接符,具体在 tnsnames.ora 文件中新加一个连接符,再重新启动监听器 lsnrctl start
19、保持 PDB 模式
完成常规配置后,当 CDB 实例关闭重新开启后会重置 PDB 的模式为 MOUNTED,此时可执行 alter pluggable database ORCLPDB2 open; 手动启动。或在 PDB 启动后使用 alter pluggable database all save state; 命令,保持状态,让 PDB 保持启动。或者通过在 CDB 新建触发器:
| 1 | SQL>create or replace trigger auto_open_pdbs | 
其他相关命令:
- alter pluggable database all except ORCLPDB2 close;,除 ORCLPDB2 外关闭全部 PDB
- alter pluggable database all open;,开启全部 PDB
- alter pluggable database all close immediate;,关闭全部 PDB
- shutdown immediate;,关闭 CDB
- startup mount;,启动 CDB
20、密码过期
1、执行 docker exec -it oracle /bin/bash 进入正在运行容器的命令行,执行 sqlplus / as sysdba 登入
2、关闭密码过期机制
| 1 | alter profile default limit password_life_time unlimited; | 
3、切换到所在容器,例如 ORCLPDB1
| 1 | alter session set container=ORCLPDB1; | 
4、重新修改用户密码 abc2,再改回旧密码 abc 即可
| 1 | alter user abc identified by abc2; | 
其他
1、 如果在 PDB 中已经存在一个用户或者角色,则在 CDB 中不能创建相同的账号或者角色名。
2、 同样在 CDB 中创建账号后不能在 PDB 中出现同名的账号,因 CDB 中的账号对所有的 PDB 都是有效的。
3、 在 CDB 中创建的账号将会在全部的 PDB 中出现,但是在 CDB 中的授权,如非特别指定的话,并不能传递到 PDB 中。
4、 针对同一个共有账号在 PDB 下创建的账号在 CDB 是看不到的。针对同一个共有账号,在 PDB 和 CDB 下创建的共有账号因在 CDB 和 PDB 下被赋予了不同的含义,故在 CDB 下创建的对象和在 PDB 下创建的对象是可以同名的,反之也成立。
其他查询
1、查看所有用户:
| 1 | select * from dba_users; | 
2、查看用户或角色系统权限(直接赋值给用户或角色的系 bai 统权限):
| 1 | select * from dba_sys_privs; | 
3、查看角色(只能查看登陆用户拥有的角色)所包含的权限
| 1 | sql>select * from role_sys_privs; | 
4、查看用户对象权限:
| 1 | select * from dba_tab_privs; | 
5、查看所有角色:
| 1 | select * from dba_roles; | 
6、查看用户或角色所拥有的角色:
| 1 | select * from dba_role_privs; | 
7.查看哪些用户有 sysdba 或 sysoper 系统权限(查询时需要相应权限)
| 1 | select * from V$PWFILE_USERS |