oracle 基于Edition Based Redefinition(EBR) 同一数据库PL/SQL多版本控制
在oracle中持续的为online(Zero Downtime)引入了大量的特性,但在国内可能用的很少,互联网搞出的“灰度发布”一词也是这个目的, 在对正常运行时间要求较⾼的数据库上,将代码更改发布到执行频繁的程序包中的 PL/SQL 会带来很多挑战。在执行程序包时,⽆法获得DDL 锁来编译程序包,那么如何在不停机的情况下做到这一点呢?
背景
在 11g Release 2 之前,您只能在 Oracle 数据库中部署每个 PL/SQL 对象的一个版本(及最新版本),在不停机的情况下将 PL/SQL 更改部署到生产中会带来以下挑战:
- 当其他⽤⼾正在编译包时,⽆法获取编译包所需的 DDL 锁
- 发布期间数据库代码可能处于不一致的状态
- 更新后的代码一经编译,⽤⼾便可立即访问。这样您就没有时间单独进行发布后测试
- 您必须仔细考虑如何在紧急情况下回滚更改
从 11.2 开始,Oracle 引入了基于版本的重新定义。这允许您在一个schema中部署同一 PL/SQL 对象的两个不同版本(或更多)。使⽤此功能,您可以将更改部署到新版本中并在将新代码提供给最终⽤⼾之前对其进行验证。这允许您编译 PL/SQL 的私有副本,而⽆需重命名对象或使⽤多个数据库。如同session 级的一些CBO init parameter。
如何启用EBR
第一步是启⽤数据库⽤⼾版本。您可以使⽤以下命令执行此操作:
alter user <username> enable editions;
请注意,这是单向操作。⽆法禁⽤⽤⼾。如果要回滚此命令,必须从备份中恢复⽤⼾或重新创建⽤⼾。并⾮所有数据库对象都是可编辑的,。如果您尝试启⽤拥有可编辑对象且依赖项不为可编辑的⽤⼾的版本,则上述命令将失败。。在 11.2 中,公共同义词是不可编辑的。如果您有任何 PL/SQL 对象,则上述语句将失败。您可以通过在启⽤版本时添加强制选项来克服此问题:
alter user <username> enable editions force;
执行此操作时要⼩心,因为这可能会导致您⽆法验证的不可编辑依赖项。例如,您将⽆法验证指向目标⽤⼾的任何公共同义词,因此必须将其替换为私有同义词。12c 中对 EBR 进行了一些改进。公共同义词是可编辑的。如果您计划在 11.2 数据库上使⽤ EBR 并遇到这些依赖关系,在⼤多数情况下,升级到 12c 会更容易。
一旦⽤⼾启⽤了版本,下一步就是创建新版本。⽤⼾必须具有“CREATE ANY EDITION”权限,您可以使⽤以下命令执行此操作:
create edition <edition name> [as child of <previous edition name>];
“as child of”子句是可选的。只能将新版本创建为当前叶版本的子版本。新版本会⾃动继承父版本的代码。所有数据库都带有 ORA$BASE 版本。这是所有新数据库的默认版本。您创建的第一个版本将是此版本的子版本。
创建版本后,您需要授予所有使⽤该版本的⽤⼾执行此操作的权限:
grant use on edition <edition name> to <username>;
创建的第一个版本 create edition edition_1; grant use on edition edition_1 to edition_user; alter session set edition = edition_1;
要恢复到上一个版本,请将会话参数重新
alter session set edition = ora$base;
如果您希望使⽤应⽤程序本身执行此操作,则需要正确定义版本。一种方法是在连接字符串中设置它。常⽤的方法有:
- 将OCI应用程序主机 ORA_EDITION 操作系统环境变量设置为所需的版本
- 对于 JDBC 连接,将 oracle.jdbc.editionName 设置为目标版本的名称
- 将数据库服务链接到版本。您可以使⽤ DBMS_SERVICE.MODIFY_SERVICE 过程执行此操作
验证当前SESSION版本,执行下面的查询:
select sys_context('USERENV', 'SESSION_EDITION_NAME') from dual;
要授予某个版本的公共访问权限,请执行以下操作 grant use on edition to public;
要设置数据库的默认版本,请运行: alter database default edition = <edition name>; --验证 select property_value from database_properties where property_name = 'DEFAULT_EDITION';
删除旧版本方法和满足条件
drop edition release_1 cascade;
- 它必须是数据库的父版本
- 一定没有⽤⼾连接到该版本
- 它不能是数据库的默认版本
- 子版本已实现父版本中的所有对象。这意味着必须在新版本中编译或删除所有对象
管理维护
使⽤ EBR 部署 PL/SQL 更改很容易。使⽤它会带来管理开销,不小心可以连上错误的版本。为了解决这个问题,我建议采取以下措施:
- 指定一个⼈来管理给定数据库的版本。确保他们记录当前正在运行的版本。此⼈还应告知发布团队在即将进行的部署中使⽤哪个版本。在所有发布⽂档中明确说明目标发布版本。
- 确保发布脚本始终将版本设置为任何部署的第一步。结合上一步,这可以降低将更改部署到错误版本的⻛险。
- 尽量减少多个版本同时运行的时间。一旦旧版本被弃⽤,请更新数据库的默认版本并撤销对旧版本的访问权限。
您可以使⽤以下查询查看数据库中当前存在哪些版本:
select * from dba_editions;
您还可以使⽤ *_AE(所有版本)视图查看有关各个版本对象的信息
支持对象
11gR2:
- SYNONYM
- VIEW
All PL/SQL object types: - FUNCTION
- LIBRARY
PACKAGE and PACKAGE BODY - PROCEDURE
- TRIGGER
- TYPE and TYPE BOD
12cR1 also includes:
- SQL translation profile
- PUBLIC SYNONYM
相关视图
- *_ERRORS_AE
- *_OBJECTS_AE
- *_EDITIONING_VIEW_COLS_AE
- *_EDITIONING_VIEWS_AE
- *_SOURCE_AE
- *_VIEWS_AE
References
11gR2 Documentation:
12cR1 Documentation:
Oracle-BASE article:
Tom Kyte’s Oracle Magazine article, Edition-Based Redefinition, Part 1:
Edition-Based Redefinition Whitepaper, Bryn Llewellyn July 2009:
对不起,这篇文章暂时关闭评论。