Edition-Based Redefinition白皮书笔记

本文为Edition-Based Redefinition: an Oracle Database capability to support online application upgrade的读书笔记。
edition-based redefinition以下简称EBR。EBR是11g引入的特性,在12c做了大的改进。

简介

应用升级需要解决以下的问题:

  • 升级中,对数据库对象的改变不应影响现有应用
  • 升级前应用执行的事务应反映到升级后应用中,反之亦然

EBR可实现以上目标:

  • 代码的改变,包括PL/SQL,表定义等,安装在新版本中
  • 数据的改变只写到新的表或新的列,老版本不会看到
  • 跨版本触发器将老版本应用所做改变反映到新版本中,反之亦然

用户目标和Oracle数据库能力

用户高可用终极目标是零宕机。例如操作系统升级,数据库升级,或迁移到新硬件平台可以采用以下方式:

  • 新建备库,与主库形成复制关系(捕获主库的变化,保持同步)
  • 停止复制,对备库端进行升级,如升级数据库,操作系统
  • 重新启用复制,使备库与主库重新同步
  • 反转复制关系,应用指向升级后的数据库

以上不涉及到数据库对象的改变,EBR支持数据库对象的改变,即在线应用升级。
在线应用维护是指数据库对象物理属性的改变,如迁移表空间,重新组织等;而在线应用升级是逻辑层面的改变。
在这里插入图片描述
以上是Oracle数据库支持的高可用特性,EBR在左下。

基于版本的重定义(EBR)

EBR依赖于3类新的对象,即edition、editioning view和crossedition trigger。

  • 若只改变视图,同义词和PL/SQL对象,edition就够了
  • 若表结构和数据的改变并是在后端完成,不涉及终端用户,则只需edition和editioning view
  • 若表结构和数据的改变是由终端用户发起,则三者都需要

Edition

editon概念

和目录一样,edition是非schema对象,由SYS拥有。所谓非schema对象,是指此对象不属于任何schema,对任何用户可见,只需使用其对象名即可引用,而不是schema.objectname的形式。
从11gR2开始,每个数据库都有一个默认版本,即ORA$BASE。

SQL> show edition

EDITION
------------------------------
ORA$BASE

创建新的版本时,必须基于一老的版本,即新版本继承于老版本。老版本只能有一个继承者。
每一个会话,只能使用一个版本:

SQL> SELECT SYS_CONTEXT('userenv', 'current_edition_name') from dual;

SYS_CONTEXT('USERENV','CURRENT_EDITION_NAME')
--------------------------------------------------------------------------------
ORA$BASE

数据库层面可以改变所使用的edition:

alter database default edition = Some_Edition

会话层面也可以修改edition,但必须没有未提交事务,并且在PL/SQL中不能修改。

editionable 对象类型,editions-enabled 用户和editioned 对象

editionable 对象类型:视图,同义词及所有PL/SQL对象(例如cross-edition trigger)对属于此类。表不是。
editions-enabled 用户:由dba_users的列editions_enabled确定,只有Y和N两个值,默认为N,在建用户时可以指定,alter user可以修改,但只能从N改为Y。sys和system用户不能设置为editions-enabled:

SQL> select distinct editions_enabled from dba_users;

E
-
N

editioned 对象:由editions-enabled 用户拥有的对象,如果是editionable 对象类型,则称为editioned 对象
非editioned 对象通过owner+name引用。editioned 对象通过owner+name+edition引用,这样在一个数据库中,一个对象就有多个版本。这是EBR的必要条件。
表dba_objects中新增了和edition相关的列:

SQL> desc dba_objects;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
...
 EDITION_NAME                                       VARCHAR2(128)
...
 EDITIONABLE                                        VARCHAR2(1)
...

实际对象,继承对象和命名解析

当前版本与对象的版本一致时,称为实际对象。对象的版本来自当前版本的父版本时,称为继承对象。
当DDL修改继承对象时,继承对象即变成实际对象。drop命令是集成对象从当前edition中删除。
editioned对象在当前edition及当前edition的子edition中可见,直到出现实际对象。
对当前edition中editioned对象的修改也会一直向下传播,直到遇到实际对象为止。

edition的退役

通过收回edition的use权限实现。

删除edition

系统默认的edition不能删除。
必须没有人使用此edition时才可删除。
或者其没有子edition,或者其子edition中没有editioned对象时才可删除。

EBR生命周期

最初只有一个edition:Pre_Upgrade
EBR期间,新增一个edition:Post_Upgrade,继承自Pre_Upgrade
升级完成后,Pre_Upgrade可以退役
由于存在多个edition,在命名解析时可能会沿着继承链回溯,不过不会有性能影响,因为这是发生在编译期间而非运行期间。

示例

以下实验在PDB: orclpdb1中进行。
首先创建一个用户appuser1:

SQL> show user
USER is "SYSTEM"

SQL> show con_name;

CON_NAME
------------------------------
ORCLPDB1
SQL> grant create session to appuser1 identified by oracle;

Grant succeeded.

SQL> grant create procedure to appuser1;

Grant succeeded.

SQL> grant create any edition to appuser1;

Grant succeeded.
SQL> alter user appuser1 enable editions;

User altered.

以应用用户登录:

SQL> show user;
USER is "APPUSER1"

create or replace procedure Hello is
begin
DBMS_Output.Put_Line('Hello from Pre_Upgrade');
end ;
/
SQL> set serveroutput on
SQL> exec Hello;
Hello from Pre_Upgrade

PL/SQL procedure successfully completed.

DBA建立新edition并赋权给应用用户:

create edition Post_Upgrade as child of ORA$BASE
/
grant use on edition Post_Upgrade to appuser1
/

以应用用户登录:

SQL> alter session set Edition = Post_Upgrade;

Session altered.

create or replace procedure Hello is
begin
DBMS_Output.Put_Line('Hello from Post_Upgrade');
end;
  5  /

Procedure created.
SQL> set serveroutput on;
begin Hello(); end;
  2  /
Hello from Post_Upgrade

PL/SQL procedure successfully completed.

SQL> alter session set edition = ORA$BASE;

Session altered.

SQL> select Sys_Context('Userenv', 'Current_Edition_Name') from dual;

SYS_CONTEXT('USERENV','CURRENT_EDITION_NAME')
--------------------------------------------------------------------------------
ORA$BASE

SQL> begin Hello(); end;
  2  /
Hello from Pre_Upgrade

PL/SQL procedure successfully completed.

最后删除edition:

SQL> drop edition Post_Upgrade;
drop edition Post_Upgrade
*
ERROR at line 1:
ORA-38811: need CASCADE option to drop edition that has actual objects


SQL> drop edition Post_Upgrade cascade;

Edition dropped.

editioning view

并非所有的对象都是editionable。11.2以后,对象分为两类,code对象和data对象。前者只有元数据,没有数据,例如存储过程;后者包含数据,例如表和索引。前者通常是editionable的,后者则不是。
如果需要多个版本的数据,例如某列变宽。有两种做法,一是建立另一张表,二是新增一个变宽的列,其它数据共享。第一种方式会有数据的开销,第二种方法的最佳实现方式是视图。也就是editioning view。
虽然物理表不能editionable,但editioning view支持不同edition下提供不同的逻辑视图。

editioning view必须满足的条件

必须返回所有行,但所有列,不允许排序。
editioning view不影响性能。
editioning view必须由editions-enabled用户拥有。
editioning view必须由表的属主拥有。
在某一editioning下,一张表只能有一个可见的editioning view。
不支持union [all], minus, 和intersect。
不支持for update子句。
from list只能是一张表。
任何列只能出现一次,不支持表达式。
不支持group by,where和having子句。
不支持order by。
不支持distinct, unique, 和 all关键字。

editioning view中允许的定义

支持with read only子句。
支持主键约束,不支持外键约束。

不同视图不支持editioning view支持的操作

所有在表上可执行的select, insert, update, delete, merge, lock table 或 explain语句都可以在editioning view中执行。
支持table-style triggers。
针对editioning view的查询支持分区扩展语法,例如:

select * from ev partition(p1)
只使用editions和editioning view的EBR

如果在升级过程中,最终用户端(应用端)并不改变数据,那么使用editions和editioning view就足够了。
最典型的例子是配置数据,通常量不会很大,但决定了应用的行为。

crossedition trigger

有时,升级时应用端必须改变数据,例如电话号码由之前的一个字段(010-12345678)变为区号(010)和号码(12345678)两个字段。或者姓名拆成姓和名两个字段。这时,老版本应用对数据的改变必须反映到新的表结构,反之亦然,这时trigger就比较适合。
crossedition trigger是一种特殊的trigger。trigger本身即editionable对象。crossedition trigger必须由editions-enabled 用户拥有,也就是说crossedition trigger总是editionable的。
另外,crossedition trigger只有在其为actual的edition中有效。
crossedition trigger只能基于表而非视图创建。

参考

  1. https://blogs.oracle.com/datawarehousing/edition-based-redefinition
  2. https://blogs.oracle.com/weblogicserver/data-source-use-of-oracle-edition-based-redefinition-ebr
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值