原标题:Oracle 18c新特性测试
7月24日Oracle 18c通用版本正式对外发布后,三墩IT人在数据库的迁移,割接和升级等方面进行了相关的测试,并分享了相关的测试结果。随后三墩IT人又着重在数据库的资源管理和数据安全进行了测试,取得了大量的测试结果,今天我们带来了这些方面的测试过程和测试结果。
资源管理
功能介绍:
Oracle 12c版本引入了多租户的概念,可以把不同的业务整合到同一套数据库中的不同租户中,但与此同时也带来了各个租户之间对于硬件资源的争用,当一个租户出现异常时可能会影响其他租户的正常运行。为实现租户间的资源均衡,限制和隔离,通过ORACLE的resource manager功能进行控制。
在Oracle 12c版本之前,resource manager用来管理数据库对于操作系统资源的控制,如果一台主机上有多个数据库,那么需要分别在对应的数据库上单独设置resource manager,无法实现资源的统一分配。在Oracle 12c增强了resource manager的功能,能够对CDB和PDB进行资源控制,在一个有多个PDB的数据库中,可以对每个PDB指定不同的资源控制方案来分配操作系统和CDB资源,实现一个数据库中多个PDB的资源的统一管理。
以下测试是基于CDB下的PDB资源管控的实施测试场景,鉴于生产环境使用版本及12C与18C关于resource manager无功能差异,此测试使用12.2版本进行。
测试场景(一):最低资源测试
测试条件
资源计划名称DAYTIME,CDB下存在3个PDB,具体资源限制如下:
测试步骤
1.创建资源计划
资源计划:DAYTIME
1).创建临时区
exec dbms_resource_manager.create_pending_area();
2).创建新的资源计划
begin
dbms_resource_manager.create_cdb_plan(
plan=> 'DAYTIME',
comment => 'DAYTIME');
end;
/
3).创建资源指令
4).验证临时区
exec dbms_resource_manager.validate_pending_area();
5).提交修改
exec dbms_resource_manager.submit_pending_area();
2.启用资源计划
[CDB级别]
alter system set resource_manager_plan ='DAYTIME';
3.验证资源控制
运行压测脚本
[分别在PDBPROD1,PDBPROD2,PDBPROD3中执行]
USER1@PDBPROD1:SQL> @run11.sql
/* 脚本为对超大表进行内容HASH运算,消耗大量的CPU及IO资源 */
查看资源控制及使用情况
抽样CPU使用情况:
期间各PDB的CPU使用情况
测试小结
1.通过共享片(shares)方式分配资源,分配资源为最低保证资源。
2.当系统资源满足最低PDB保证资源后,剩余资源被多个PDB共享。
3.若CPU上限不进行限制,CPU资源被所有PDB共享。
4.这种资源控制方式无法实现资源的有效隔离,仍然会导致一损皆损的结果。
测试场景(二):限制资源测试[CPU]
测试条件
资源计划名称DAYTIME,CDB下存在3个PDB,具体资源限制如下:
测试步骤
1.修改资源计划
2.验证资源控制
运行压测脚本
查看资源控制及使用情况
抽样CPU使用情况:
/* PDB的CPU使用占比与CPU使用限制配置相一致,基本保持在4:1:1的关系 */
抽样IO资源使用情况:
/* PDB的IO使用占比基本保持在4:1:1的关系 */
期间各PDB的CPU使用情况
期间各PDB的IOPS使用情况
测试小结:
1. 若cpu资源上限作出限制,可以看到cpu总使用率在60%以下,资源分配为4:1:1
2. 随着cpu资源上限作出限制,可以看到IO的总体使用率也会得到相应的控制,呈现出一种正相关的变化趋势
3. 能够有效控制cpu的使用情况,合理分配cpu资源,能够保护各个PDB和操作系统的CPU资源使用
测试场景(三):并行资源测试
测试条件
资源计划名称DAYTIME,CDB下存在3个PDB,具体资源限制如下:
测试步骤
1.修改资源计划
2.验证并行测试
运行压测脚本
[分别在PDBPROD1,PDBPROD2,PDBPROD3中执行]
PDBPROD1:脚本并行设置70(小于限制80),启动顺序1
PDBPROD2:脚本并行设置30(小于限制40),启动顺序2
PDBPROD3:脚本并行设置19(小于限制20),启动顺序3
查看资源控制及使用情况
/* 三个PDB下的压测脚本均可按照设定并行度正常执行,未出现排队现象 */
调整压测并行度测试
按照上面的方法分别模拟四种情况
1、脚本并行设置100(大于限制80),启动顺序1
脚本并行设置30(小于限制40),启动顺序2
脚本并行设置21(大于限制20),启动顺序3
/*
1. 通过资源监控发现,PDBPROD1并行100大于限制80,任务处于运行状态,
2. PDBPROD2并行30小于40限制,任务正常运行.
3. PDBPROD3并行21大于20限制,但任务被阻塞,处于排队状态.
*/
2、脚本并行设置100(大于限制80),启动顺序2
脚本并行设置30(小于限制40),启动顺序1
脚本并行设置21(大于限制20),启动顺序3
/*
1. 通过资源监控发现,PDBPROD1并行100大于限制80,任务处于排队状态,
2. PDBPROD2并行30小于40限制,任务正常运行.
3. PDBPROD3并行21大于20限制,任务处于排队状态.
*/
3、脚本并行设置100(大于限制80),启动顺序2
脚本并行设置30(小于限制40),启动顺序1
脚本并行设置19(小于限制20),启动顺序3
/*
1. 通过资源监控发现,PDBPROD1并行100大于限制80,任务处于排队状态,
2. PDBPROD2并行30小于40限制,任务正常运行.
3. PDBPROD3并行19小于20限制,任务正常运行.
*/
4、脚本并行设置100(大于限制80),启动顺序3
脚本并行设置30(小于限制40),启动顺序1
脚本并行设置19(小于限制20),启动顺序2
/*
1. 通过资源监控发现,PDBPROD1并行100大于限制80,任务处于排队状态,
2. PDBPROD2并行30小于40限制,任务正常运行.
3. PDBPROD3并行19小于20限制,任务正常运行.
*/
测试小结
1.资源空闲情况下,首个运行并行的PDB,并行不受资源管理器控制,可超过限制运行。
2.多个PDB都存在并行的情况下,并行控制与资源管理器配置相一致。
3.超出PDB资源控制的那一部分会话需要等待有空闲资源后才能继续执行。
资源隔离测试小结
经过测试,基于CDB下的PDB资源控制,主要得出如下结论:
1.基于资源片(shares)的资源分配,若不配置资源上限,所有PDB共享所有硬件资源。
2.CDB级别支持CPU,PARALLEL及内存(Exadata)的上限资源控制,IO没有资源上限控制参数。通过资源上限控制(CPU,PARALLEL),可严格控制各PDB资源使用。
3.实际测试发现,针对并行控制,初次运行并行的PDB并不受RESOURCE MANAGER控制。当资源空闲时,可以超过限制获得更多并行资源。当系统繁忙时,且分配资源达到配置上限时,新申请的资源的会话将会进行等待。
数据安全
功能介绍:
数据编写功能是Oracle从12c之后提供的高级安全加密功能,对应用前台展示后台查询时提供敏感数据加密保护。如应用用户在查询某表时,某列的数据属于敏感数据,可以对该列进行加密改写后显示给该用户,并且不会影响到底层存储的真实数据。
数据编写的加密类型包括:
»全数据编写
被保护列数据内容被完全编写,不保留任何原数据内容。对于用户查询返回的编写值取决于该列的数据类型。如number类型的列被编写成全部是0,character数据类型的列全部被编写为空格。
»部分数据编写
被保护列数据内容被部分编写,不保留任何原数据内容。如xxxx-xxxx-xxxx-1234
»随机数据编写
被保护列数据内容被随机编写,原数据被随机生成值替代。如数据1234567被随机转换为 83933895.LOB类型不被支持。
»正则表达式数据编写
被保护列数据内容被正则表达式方式编写,原数据被正则表达式替代。
»NULL数据编写
被保护数据列被NULL值替代。
数据编写范围影响:
»SYS用户不受数据编写影响,控制SYSDBA的强制访问需要通过Oracle Database Vault实现
»授予EXEMPT REDACTION POLICY系统权限的用户不受影响
»授予DBA权限的用户不受影响,因DBA权限包含EXP_FULL_DATABASE角色
»EXP_FULL_DATABASE角色包好EXEMPT REDACTION POLICY系统权限。
»制成物化视图,刷新时不会被Redaction。
»在启用了数据改写策略的表上无法进行全表的 CTAS 操作。
»数据改写发生在查询结果返回阶段,不影响查询where条件,不影响数据存储。
测试步骤
配置全局策略表达
[sqlplus下执行]
#创建全局策略表达
BEGIN
DBMS_REDACT.CREATE_POLICY_EXPRESSION (
policy_expression_name => 'REDACT_EXP_POLICY',
expression => 'SYS_CONTEXT(''USERENV'',''SESSION_USER'') IN(''USER1'',''USER2'')',
policy_expression_deion => 'Determines whether the column will be redacted');
END;
/
#该策略表达配置使USER1和USER2两个用户受数据编写影响
以全数据编写测试为例,其他编写方式与此过程类似
默认情况下,全数据编写的编写策略如下:
1). 字符数据类型转换为空格。
2). 数字数据类型转换为0。
3). 日期类型转换为2001年1月1号,如01-JAN-01。
说明:当针对表的列添加数据编写策略过程中,若未指定function_type,默认为全数据编写。
全数据编写部署
#添加策略
BEGIN
DBMS_REDACT.ADD_POLICY (
object_schema => 'hr',
object_name => 'employees',
policy_name => 'hr_employees_policy',
expression => '1=0');
END;
/
#数值型
BEGIN
DBMS_REDACT.ALTER_POLICY (
object_schema => 'hr',
object_name => 'employees' ,
policy_name => 'hr_employees_policy',
function_type => DBMS_REDACT.FULL,
action => DBMS_REDACT.ADD_COLUMN,
column_name => 'SALARY' );
END;
/
#字符型
BEGIN
DBMS_REDACT.ALTER_POLICY (
object_schema => 'hr',
object_name => 'employees' ,
policy_name => 'hr_employees_policy',
function_type => DBMS_REDACT.FULL,
action => DBMS_REDACT.ADD_COLUMN,
column_name =>'FIRST_NAME' );
END;
/
#此处 function_type类型可以换成DBMS_REDACT.FULL,DBMS_REDACT.NULLIFY,DBMS_REDACT.PARTIAL,DBMS_REDACT.REGEXP,DBMS_REDACT.RANDOM代表了不同的编写类型,可以参考官方文档进行相关编写类型的测试。
#应用策略表达
BEGIN
DBMS_REDACT.APPLY_POLICY_EXPR_TO_COL (
object_schema => 'hr',
object_name => 'employees',
column_name => 'salary',
policy_expression_name => 'REDACT_EXP_POLICY');
END;
/
BEGIN
DBMS_REDACT.APPLY_POLICY_EXPR_TO_COL (
object_schema => 'hr',
object_name => 'employees',
column_name => 'first_name',
policy_expression_name => 'REDACT_EXP_POLICY');
END;
/
验证数据编写结果
[查看数据访问策略和编写策略]
可以从视图
redaction_expressions,redaction_policies,redaction_columns,redaction_values_for_type_full查询以下结果。
[HR访问数据]
HR@DB183:SQL>
HR@DB183:SQL> select first_name,salary from hr.employees where rownum<20;
FIRST_NAME SALARY
---------------------------------------- ----------
Steven 24000
Neena 17000
Lex 17000
[USER1访问数据]
USER1@DB183:SQL> select first_name,salary from hr.employees where rownum<20;
FIRST_NAME SALARY
---------------------------------------- ----------
7
7
7
#修改默认全数据编写策略
EXEC DBMS_REDACT.UPDATE_FULL_REDACTION_VALUES (varchar_val=>'A',number_val => 999); /* 修改默认策略需要重启数据库后生效 */
验证编写结果
[HR用户]
HR@DB183:SQL> select first_name,salary from hr.employees where rownum<20;
FIRST_NAME SALARY
---------------------------------------- ----------
Steven 24000
Neena 17000
Lex 17000
[USER1用户]
USER1@DB183:SQL> select first_name,salary from hr.employees where rownum<20;
FIRST_NAME SALARY
---------------------------------------- ----------
A 999
A 999
A 999
数据编写下DML及CTAS测试
INSERT测试
#测试场景1:全列插入
USER1@DB183:SQL> insert into hr.t1 select * from hr.t1;
insert into hr.t1 select * from hr.t1
ERROR at line 1:
ORA-28081: Insufficient privileges - the command references a redacted object.
#测试场景2:排除数据编写列插入
USER1@DB183:SQL> insert into hr.t1(EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,HIRE_DATE,JOB_ID,SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID,CREDIT_ID,CREDIT_ID2)
2 selectEMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,HIRE_DATE,JOB_ID,SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID,CREDIT_ID,CREDIT_ID2 from hr.t1;
107 rows created. <<< 可成功执行
#测试场景3:数据编写列插入
USER1@DB183:SQL> insert into hr.t1(phone_number) select phone_number from hr.t1;
insert into hr.t1(phone_number) select phone_number from hr.t1
ERROR at line 1:
ORA-28081: Insufficient privileges - the command references a redacted object.
#测试场景4:数据源从非数据编写列获取
USER1@DB183:SQL> insert into hr.t1 select * from hr.t2;
214 rows created. <<< 可顺利实现插入
UPDATE测试
#测试场景1:对数据编写列进行UPDATE,条件为非数据编写列
USER1@DB183:SQL> update hr.t1 set phone_number='234.123.878' where employee_id=100;
1 row updated. <<< 操作可正常执行
#测试场景2:对数据编写列进行UPDATE,条件为数据编写列(真实数据)
USER1@DB183:SQL>
USER1@DB183:SQL> update hr.t1 set phone_number='234.123.878' where phone_number='515.123.4567';
1 row updated. <<< 操作可正常执行
#测试场景3:对数据编写列进行UPDATE,条件为数据编写列(非真实数据)
USER1@DB183:SQL> update hr.t1 set phone_number='234.123.878' where phone_number='**-***-4567';
0 row updated. <<< 操作可正常执行,但无数据行被修改
DELETE测试
#测试场景1:对数据编写列进行DELETE,条件为非数据编写列
USER1@DB183:SQL> delete from hr.t1 where employee_id=110;
1 row updated. <<< 操作可正常执行
#测试场景2:对数据编写列进行DELETE,条件为数据编写列(真实数据)
USER1@DB183:SQL> delete from hr.t1 where phone_number='234.123.878';
1 row updated. <<< 操作可正常执行
#测试场景3:对数据编写列进行DELETE,条件为数据编写列(非真实数据)
USER1@DB183:SQL> delete from hr.t1 where phone_number='***-***-878';
0 row updated. <<< 操作可正常执行,但无数据行被修改
CTAS测试
# 数据编写列CTAS测试
USER1@DB183:SQL> create table t1 as select * from hr.employees;
create table t1 as select * from hr.employees
ERROR at line 1:
ORA-28081: Insufficient privileges - the command references a redacted object.
数据编写测试小结
1. 数据编写策略在插入包含被编写过数据时会禁止插入,插入空值和真实数据,可以顺利插入。
2.数据编写策略不会对表UPDATE产生影响,测试用户通过修改编写列的非真实数据无法达到修改目的。
3. 数据编写策略不会对表DELETE产生影响,测试用户通过删除编写列的非真实数据无法达到删除目的。
4.数据编写策略不支持CTAS操作,用户没有办法通过此方式获取到真实数据。
5. 通过数据编写功能测试,数据编写(REDACTION)可分别从全数据编写,部分数据编写,NULL数据编写,随机数据编写及正则表达数据编写五个方面对数据进行安全保护,防止敏感数据被意外查看。五个方面针对不同的数据类型可灵活配置,功能实现上和预期一致。
?
测试总结
1.资源隔离:在生产环境中,为了达到资源隔离的目的,在CDB层面设置和分配CPU,PARALLEL资源可以起到真正的隔离效果。在12c使用的过程中,应在上线前尽量判断和规划好业务所属的数据处理类型(OLTP,OLAP)和业务的重要程度,把数据处理类型和重要程度相近的业务放在一起,在此基础上进行资源的平衡限制和隔离,才能有效充分的利用现有资源,最终保证业务的安全连续可靠。
2.数据编写:在生产环境中,对于测试环境中敏感数据的保护通常是通过第三方工具或脚本进行原始数据修改达到数据保护的要求。通过Oracle 12c新增的数据编写功能能通达到同样的目的,由于数据编写功能不是对真实数据进行直接覆盖,只是在用户级别进行了数据展现上改写,还需对用户加强管理,避免管理用户密码和管理权限的泄露。
Oracle18c在各个方面都做了全面提升,这些新增的功能还需要在生产实践中验证稳定性。后续还将进行应用连续性的测试,敬请期待。
责任编辑: