前言:

Oracle 12c的多租户(multitenant)环境与SQL Server的架构非常相似,CDB$ROOT类似于master、PDB$SEED类似于model、各个pluggable database就相当于普通的业务库。
官方宣传了12c的很多好处但其实没卵用,12c设想通过合并多个库来避免DBLINK的性能问题,但其实还是通过压榨单一服务器来实现的,其他好处诸如PDB迁移方便、JSON支持、资源组、索引压缩、in-memory支持等等要么是炒冷饭,要么实际适用场景很少,不过这些新特性都还有待继续研究,一步一步来。
首先必须要解决的是登录问题,12c的多租户环境下用户与以前不同了,以前的用户性质都是一样的,而在12c中一个实例下可以有多个可插拔的数据库,因此用户管理与之前就有很大区别了,本文介绍12c用户及其管理,以12.2.0.1版本为例,所有观点来源于如下官网链接:
本文主要包含以下六个部分:
  • 关于用户安全的简易说明
  • 创建用户
  • 更改用户
  • 配置用户资源限额
  • 删除用户
  • 用户和profile的的数据字典

一、关于用户安全的简易说明:


每个数据库都有自己的用户列表,在创建用户时你可以为这个用户设置一系列的登录limits或resource limits,或者使用profile实现此功能,profile就是一个用户所拥有的属性的集合,你可以查看dba_profiles来详细了解。
此外你还可以为用户赋予一系列的权限和角色,参考:Configuring Privilege and Role Authorization
 
二、创建用户

这部分涉及的内容很多,保险起见还是全部列出来的比较好。
  • 关于Common User和Local User
在多租户的环境中,common user可以访问整个CDB而local user只能访问特定的PDB,关于CDB与PDB的关系这里用官网的一幅图来表示:

可以看到CDB其实就是指实例下的所有数据库,包含ROOT、Seed和其他所有PDBs,整个Instance可以看做一个容器,即Container DB(CDB).

你可以使用sysdba用户来启动PDB,有以下两种方式:

1.alter session set container=orclpdb1;
alter database open;
--对应关闭方式为shutdown immediate;
2.alter pluggable database orclpdb1 open;
--对应关闭方式为alter pluggable database orclpdb1 close;
Ps:PDB的关闭是指将PDB由open变为mount状态,彻底shutdown需要到root中关闭整个实例。

关于Common user:

Common user必须以C##或者c##开头,你可以通过修改common_user_prefix参数来更改这个prefix,而Local user则必须避免以这个prefix开头。
Common user的身份和密码对于每个PDB来说都是可见的,只要有合适的权限common user也可以操作PDB。
Common user通常用于在root中操作PDBs,例如插拔PDB数据库、更改PDB状态或者为CDB指定临时表空间等。
Common user只能在cdb$root中创建,cdb$root中也只能创建common user。
举例来讲,common user可做的操作有:创建或修改common/local user、向其他common/local user赋权限或者赋角色、对整个CDB执行ALTER DATABASE开头的恢复语句、通过ALTER PLUGGABLE DATABASE语句来来更改PDB的状态(必须是连接到CDB$ROOT库时)。当然一个local user如果有权限也可以更改其自身PDB的状态。
Oracle的系统用户如sys、system等,就是common user,即可操作ROOT数据库也可以操作任意PDB,除非某个PDB开启Vault-enabled来限制系统用户的权限。

当你将一个non-CDB的数据库作为PDB插入到CDB中时:

  1. non-CDB的系统用户将会与CDB common user合并,即non-CDB中的系统用户将会新增到CDB中,如果username冲突则不新增,这些冲突系统用户的密码全部按照CDB的来,原密码失效。
  2. 如果你曾经更改过原non-CDB系统用户的权限,那么合并之后这些差异权限只对这个PDB生效,对其他PDB无效。这里还不知道如果少了权限合并之后是不是依然少,有需要的时候再测试下好了。
当你将一个PDB插入CDB时:
  1. 原PDB的common user会失去它所有的公共权限,包括set container的权限。
  2. 如果目标CDB有与PDB同名的common user,那么这两个common user合并,CDB的common user密码优先生效。而PDB中其他不同名的common user将会被锁定。你可以对这些锁定的common user做如下任意一种处理:
    • 不处理这些locked用户,在权限适当的情况下你依然可以使用这些schema下的对象。
    • 使用EXPDP导出这些用户下的数据并导入到另一个用户下,然后删掉此locked user。
    • 关掉PDB,连接到CDB$ROOT,创建同名的common user,然后重开PDB,Oracle会自动处理权限差异,此时你可以unlock这些用户,他们的本地权限保持不变。
关于Local user:
Local user就是只存在于PDB中的用户,local user可以拥有管理类权限,但是这类权限只对local user所在的PDB有效。
Local user与common user的区别可以概括为以下几点:
  1. Local user不能创建common user,也不能在cdb$root中被授予权限。而common user只要有合适的权限,就能创建、修改common/local user,就能公共的或本地的grant/revoke权限。Local user如果权限充足,可以创建、修改local user,也可以在PDB中向common/local user赋权限。
  2. 你可以向local user赋予公共角色或权限(类似于select any table这种),但是这些公共角色或权限包含的权限只对其所属PDB有效。
  3. Local user在一个PDB中应当是唯一的。
  4. 如果local user有合适的权限,那么它也可以访问common user里的对象。
  5. Local user只能在PDB中被创建,PDB中也只能创建local user而不能创建common user。
  6. 你可以根据版本来选择是否禁用local user,但是却不能这么操作common user。
  • 创建用户示例

创建common user:

$ sqlplus / as sysdba
SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 ORCLPDB1 READ WRITE NO
4 ORCLPDB2 MOUNTED
SQL> show con_name
CON_NAME
------------------------------
CDB$ROOT
SQL> alter pluggable database orclpdb1 open;
Pluggable database altered.
SQL> create user c##test identified by test container=all;
--common user只能以c##开头,且强制container=all,创建时可以不用写container=all。
SQL> grant dba to c##test;
--至此common user c##test创建完毕,但是目前为止这个common user只能操作CDB$ROOT schema对象下的objects和创建PDB的local user,并没有操作PDB下objects的权限,一般来说common user不必有此权限,但是如果你想拥有,那么:
SQL> alter session set container=orclpdb1; --切换至orclpdb1的PDB后再次grant权限
SQL> grant dba to c##test;
--至此common user c##test就拥有了操作PDB orclpdb1下objects的权限了。但是这种common user删除时必须添加cascade:
SQL> drop user c##test;
drop user c##test
*
ERROR at line 1:
ORA-65048: error encountered when processing the current DDL statement in pluggable database ORCLPDB1
ORA-01922: CASCADE must be specified to drop 'C##TEST'
SQL> drop user c##test cascade;
User dropped.

创建local user:

$ sqlplus / as sysdba
SQL> alter session set container=orclpdb1;
SQL> create user test identified by test default tablespace users quota 100M on example quota 200M on test temporary tablespace temp profile default container=current;
--local user只能以非c##开头,且强制container=current,创建时可以不用写container=current。
SQL> grant connect,resource,unlimited tablespace to test;
$ sqlplus test/test@localhost/orclpdb1
--至此local user创建完毕。
--需要特别注意的一点是:12c的resource角色中已经不包含unlimited tablespace权限因此需要单独赋予,或者通过quota项来分配一定的表空间限额。
  • 创建用户总结:
一般来说没有必要创建除系统用以外的common user,或者只需要创建一个不含操作具体PDB权限的common user,common user不应当用于操作具体业务数据,正如官方说明的那样,common user通常的操作应当是:
  创建或修改common/local user、向其他common/local user赋权限或者赋角色、对整个CDB执行ALTER DATABASE开头的恢复语句、通过ALTER PLUGGABLE DATABASE语句来来更改PDB的状态(必须是连接到CDB$ROOT库时)。
我们可以使用如下SQL来查看PDB或CDB$ROOT库内的用户:

$ sqlplus / as sysdba
SQL> alter session set container=orclpdb1;
SQL> set lines 200
SQL> set pages 100
SQL> col username for a40
SQL> select USERNAME,ACCOUNT_STATUS,COMMON from dba_users;
--结果可以看到common user是在所有PDB中可见的,在单个PDB中查询dba_users你能看到所有common user和属于本PDB的local user。

再来考虑一种特殊情况,假如我们需要在一个PDB中访问另一个PDB中的数据呢?
使用local user是不可能的,因为local user完全PDB隔离,就算local user被赋予了类似dba、select any table这些公共权限,也只是在PDB内有效,无法跨库访问,那么只能使用common user。

接下来举例common user跨PDBs访问:

SQL> show pdbs;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 ORCLPDB1 READ WRITE NO
4 ORCLPDB2 READ WRITE NO
--我们有两个PDB:orclpdb1和orclpdb2都是open状态,各自有一个scott用户,用户下分别有一个test1、test2表。我们先创建一个common user:
$ sqlplus / as sysdba
SQL> create user c##scott identified by tiger;
SQL> grant connect,resource,unlimited tablespace,select any table,create view to c##scott;
--然后在orclpdb1中给c##scott赋权限
SQL> alter session set container=orclpdb1;
SQL> grant connect,resource,unlimited tablespace,select any table,create view to c##scott;
--接下来在orclpdb2中给c##scott赋权限
SQL> alter session set container=orclpdb2;
SQL> grant connect,resource,unlimited tablespace,select any table,create view to c##scott;

至此c##scott用户就有了在两个pdb中查询的权限,但是此权限是严格PDB隔离的,不能跨库查询。虽然不能像SQL Server那样跨库直接查询,不过oracle却提供了变通的办法--CONTAINERS子句,参考网址如下(此特性开始于12.1.0.2版本):

举例:SELECT ename FROM CONTAINERS(scott.emp) WHERE CON_ID IN (45, 49);

想要使用CONTAINERS子句必须满足以下条件:

1.CONTAINERS子句中的表、视图或同义词必须在ROOT和所有PDB中都存在。
2.CONTAINERS子句中涉及的表、视图的属主必须是执行SQL语句的common user;如果是同义词,那么这个同义词必须是引用的此common user下的表或视图。
3.包含CONTAINERS子句的SQL必须在CDB$ROOT数据库下使用common user执行。

如果CONTAINERS子句涉及的表里有以下列类型,那么会被自动过滤掉:

1.用户定义的类型:object types, varrays, REFs, and nested tables
2.系统类型:ANYTYPE, ANYDATASET, URI types, SDO_TOPO_GEOMETRY, SDO_GEORASTER, and Expression
看完以上5条要求后突然发现这些要求很奇葩,如果CONTAINERS子句中的表、视图或同义词必须在ROOT和所有PDB中都存在,那我还为什么还要跨PDB查询,直接在ROOT中查不就得了?

稍微思考和实践了一下,发现使用CONTAINERS子句的条件应该是:

  • 必须使用common user在CDB$ROOT中查询
  • CONTAINERS()方法的输入是表、视图或同义词,这个对象必须在CDB$ROOT中有个名称+结构完全相同的对象,无论是表还是视图还是同义词,表可以没有数据。
  • 必须使用执行此查询的common user到表所在的PDB中创建一个同名view,这需要common user拥有查询此表的权限。

那么接着上边的实例就可以很容易的进行跨PDB查询了:

1.首先我们使用common user c##scott在orclpdb1中创建针对scott.test1的视图:
$ sqlplus c##scott/tiger@orclpdb1
SQL> create view test1 as select * from scott.test1;
2.然后使用common user c##scott在CDB$ROOT中创建同名的表或者视图:
$ sqlplus c##scott/tiger
SQL> create table test1(name varchar2(20));
3.此时我们就可以使用SQL查询了:
SQL> select * from CONTAINERS(test1) where con_id=3;
4.如果还需要联结查询orclpdb2中的test2表,那么:
$ sqlplus c##scott/tiger@orclpdb2
SQL> create view test2 as select * from scott.test2;
$ sqlplus c##scott/tiger
SQL> create table test2(name varchar2(20));
5.这样就相当于test1和test2在CDB$ROOT中都有了一个接口,我们通过接口访问相应PDB中的common user下的视图,视图又是直接定义在最终表上的。
画一幅图来直观的表示:

三、修改用户

修改用户与创建用户的语法很相似:

--一个官方示例:
ALTER USER c##hr_admin
DEFAULT TABLESPACE data_ts
TEMPORARY TABLESPACE temp_ts
QUOTA 100M ON data_ts
QUOTA 0 ON test_ts
SET CONTAINER_DATA = (emp_db, hr_db) FOR V$SESSION
CONTAINER = CURRENT;
--有以下几个地方需要解释:
1.QUOTA的大小表示在表空间上限额的总大小,而非增/减量。
2.SET CONTAINER_DATA表示此common user在root中访问v$session时可以获取到emp_db和hr_db相关的session信息。

此外一般用户的密码可以通过alter user语句修改,而sys密码可以通过orapwd工具修改:

orapwd file='orapworcl' force=y
orapwd input_file='orapworcl' file='orapwd' sys=y force=y
 
四、配置用户资源限额

这点可以通过一个视图很容易的看到:

因此修改用户资源限额就很简单了,例如:
alter user scott limit password_life_time unlimited;
--或者新建一个profile,然后将其指定为用户的profile:
CREATE PROFILE profile_scott LIMIT
FAILED_LOGIN_ATTEMPTS 6
PASSWORD_LIFE_TIME 60
PASSWORD_REUSE_TIME 60
PASSWORD_REUSE_MAX 5
PASSWORD_LOCK_TIME 1/24
PASSWORD_GRACE_TIME 10
PASSWORD_VERIFY_FUNCTION DEFAULT;
alter user scott profile profile_scott;

五、删除用户


六、用户和profile涉及的数据字典

ALL_OBJECTS
Describes all objects accessible to the current user
ALL_USERS
Lists users visible to the current user, but does not describe them
DBA_PROFILES
Displays all profiles and their limits
DBA_TS_QUOTAS
Describes tablespace quotas for users
DBA_OBJECTS
Describes all objects in the database
DBA_USERS
Describes all users of the database
DBA_USERS_WITH_DEFPWD
Lists all user accounts that have default passwords
PROXY_USERS
Describes users who can assume the identity of other users
RESOURCE_COST
Lists the cost for each resource in terms of CPUs for each session, reads for each session, connection times, and SGA
USER_PASSWORD_LIMITS
Describes the password profile parameters that are assigned to the user
USER_RESOURCE_LIMITS
Displays the resource limits for the current user
USER_TS_QUOTAS
Describes tablespace quotas for users
USER_OBJECTS
Describes all objects owned by the current user
USER_USERS
Describes only the current user
V$SESSION
Lists session information for the current database session
V$SESSTAT
Displays user session statistics
V$STATNAME
Displays decoded statistic names for the statistics shown in the V$SESSTAT view

Oracle 12c用户和安全管理的更多相关文章

  1. Oracle 12c 用户创建、角色、权限

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAd4AAADHCAIAAAA4UqVzAAAgAElEQVR4nOy9Z5Bk13UmyN/6vZrlrG

  2. oracle 12c 创建PDB用户即Local User (PDB与CDB)

    Oracle 12C用户创建与表空间分配  数据库安装完成后,首先用系统用户链接数据库容器(CDB), 在数据库容器(CDB)中创建表空间‘imei’ SQL>create tablespace ...

  3. Oracle 12c 使用scott等普通用户的方法

    目录: 一.前言 二.使用普通用户 三.自动启动PDB 一.前言 最近电脑上安装了oracle 12c数据库,想体验下新特性.安装完后,便像11g一样在dos窗口进行下面的操作: SQL Produc ...

  4. Oracle 12c创建用户时出现“ORA-65096: invalid common user or role name”的错误

    这篇文章主要介绍CDB和PDB的基本管理,资料来源oracle官方. 基本概念: Multitenant Environment:多租户环境 CDB(Container Database):数据库容器 ...

  5. 转 Oracle 12C 之 CDB/PDB用户的创建与对象管理

    在Oracle 12C中,账号分为两种,一种是公用账号,一种是本地账号(亦可理解为私有账号).共有账号是指在CDB下创建,并在全部PDB中生效的账号,另一种是在PDB中创建的账号. 针对这两种账号的测 ...

  6. 转 Oracle 12c 使用scott等普通用户的方法

    一.前言 最近电脑上安装了oracle 12c数据库,想体验下新特性.安装完后,便像11g一样在dos窗口进行下面的操作: SQL*Plus: Release 12.1.0.2.0 Productio ...

  7. Oracle 12c 创建新的数据库实例、用户

    前提:安装好了Oracle 12c数据库,已有一个数据库实例xe,登录用户/密码:system/oralce 我用的是docker安装的Oracle 12c的实例: docker run --name ...

  8. 将Oracle 12c的某用户数据迁移至OracleXE的用户

    前言:OracleXE全称为oracle database 11g express edition .Oracle Database 11g Express Edition是 Oracle 数据库的免 ...

  9. Oracle 12c 添加scott用户

    对于熟悉Oracle或者接触过Oracle的人,scott这个用户大家一定相当的熟悉.12c推出了可插拔数据库,在一个容器cdb中以多租户的形式同时存在多个数据库pdb.pdb中默认不包含scott用 ...

随机推荐

  1. 白话说java gc垃圾回收

    gc是java区别于其他好几门语言(c/c++)的一个代表功能(当然也有很多可以自动管理内存的语言,如所有的脚本语言,你根本不知道内存管理这回事)! 当然,之所以要把c/c++和java相比,是因为j ...

  2. kubernetes---kubectl 管理集群资源

    由于我现在的集群是把虚拟机的master文件直接拷贝过来的,所以之前的node节点是不存在的,只有k8s-ubuntu-1是新加入的,所以我要把上面之前创建的资源删除 删除deployment--&g ...

  3. mybatis xml < >

    [参考文章]:mybatis 中的 xml 配置文件中 ‘<’. ‘>’ 处理 1.使用转义字符将 ‘<’. ‘>’ 替换掉 描述 字符 转义字符小于号 < <大于 ...

  4. Python内置函数(7)——bytearray

    英文文档: class bytearray([source[, encoding[, errors]]]) Return a new array of bytes. The bytearray cla ...

  5. 关于pycharm安装出现的interpreter field is empty,无法创建项目存储位置

    关于pycharm安装出现的interpreter field is empty(解释器为空) 关于pycharm安装出现的interpreter field is empty,无法创建项目存储的位置 ...

  6. 死磕 java集合之WeakHashMap源码分析

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. 简介 WeakHashMap是一种弱引用map,内部的key会存储为弱引用,当jvm gc的时 ...

  7. Recursion之Demo

    Model: public class PerSon { [DisplayName("标识id")] public string id { get; set; } [Display ...

  8. qt 标签 QTextBrowser QLabel

    使用标签控件时我首先想到的就是QLabel,QLabel支持自动换行,并可以解析富文本,是一个不错的选择,这也使的我并没有去深入了解其他的可以有 同样效果的控件,本篇文字我也主要是讲解标签的用法,可以 ...

  9. Python爬虫入门教程 39-100 天津市科技计划项目成果库数据抓取 scrapy

    爬前叨叨 缘由 今天本来没有打算抓取这个网站的,无意中看到某个微信群有人问了一嘴这个网站,想看一下有什么特别复杂的地方,一顿操作下来,发现这个网站除了卡慢,经常自己宕机以外,好像还真没有什么特殊的.. ...

  10. MVC模型注解

    首先,model是通过ef自动是生成的实体. 添加模型注解的意思就是在注册的时候自动验证用户所填信息是否符合我们规定的要求(这是我们做这个例子的要求) 首先给大家先展示一下效果吧. 然后Email是点 ...