在线重定义的补充测试

    在很多时候,我们都是需要保持业务的可持续性,尽管说DDL的过程持续时间很短,但是在线业务出现,就会阻塞DML,导致业务访问中断,事务收到影响,所以在有些场景下,高可用的需求可能比性能的需求优先级还要高一些。
    比如一个分区表,突然发现分区的规则存在一些问题,如果需要重新规划分区,部署,可能对于在线业务影响较大,能不能平滑的过渡到重新规划的分区模式下。
    比如一个普通表,随着数据量的增加发现已经存在一些管理瓶颈,比如历史数据的清理比较麻烦,想改为分区表的方式
    比如一个表需要添加若干字段,数据类型也需要调整等等,这类变更如果通过DDL完成对于在线业务的影响范围较大
    比如一个表所在的分区空间不足,希望能够在业务低峰期进行数据的重构。
有了在线重定义,这些看似困难的工作就会存在可能性,当然万事皆须付出代价,那就是在线重定义本身会消耗系统资源,这个需要合理评估,找到一个合适的时间点来完成。毕竟为了完成高可用的需求而带来了严重的性能问题,那就得不偿失了。
    有些场景还是不大适合在线重定义的,比如一个数据库的表大小为50G,空间剩余不足10G,我们如果使用在线重定义的方案,那么就会存在很大的隐患。因为在线重定义本质上还是需要做一次底层的数据复制。这个就需要消耗系统资源,磁盘空间。
    在线重定义的一个亮点就是保持数据的可持续访问,基本原理是通过物化视图的prebuilt方式完成,所以这种方案本身就是高可用,物化视图的过程中对外是始终保持可访问的连续性状态,那么对于权限的控制则是这个之外的,所以我格外关心这部分的内容。如果我们的环境存在下面这样的情况,到底在线重定义的过程中是否会很稳定呢,我们可以做对比测试来验证。
如果存在大量的连接用户,在线重定义是否依然能够保证业务的可持续进行。

尽管我们知道从技术原理上是可以支持的,但是如果进一步验证测试,我想就需要更全面的测试环境了。
我们分为三个场景来测试。
第一个是通过shell不断生成会话去使用SQL调用基表的数据,看看是否会有中断。
第二个是通过一个已经存在的会话窗口不断的通过SQL去调用基表的数据,查看是否中断
第三个是通过大量的DML操作,查看在线重定义的过程中,是否依然能够稳定运行。

我们初始化了一下的数据。
我们创建基表用户ref_owner,连接用户ref_conn
创建基表test_online_ref
## init
set echo on
create user ref_owner identified by oracle;
create user ref_conn identified by oracle;
grant connect,resource to ref_owner;
grant connect to ref_conn;
grant create synonym to ref_conn;

##owner account: ref_owner
conn ref_owner/oracle

CREATE TABLE test_online_ref
   (  
   col1 varchar2(30),  
   col2 DATE  
   )  ;
alter table    test_online_ref modify(col1 primary key);
生成近300万数据
insert into test_online_ref select level,sysdate+level*0.01 from dual connect by level<3000000;
commit;
grant select,delete,insert,update on ref_owner.test_online_ref to  ref_conn;
然后在连接用户创建同义词。
##connect account: ref_conn
conn ref_conn/oracle
create synonym ref_conn.test_online_ref for ref_owner.test_online_ref;
select count(*)from ref_conn.test_online_ref;
然后创建变更后的表。表结构信息可以根据需求来定义改变,比如从改一个普通表变为分区表。
conn ref_owner/oracle
CREATE TABLE new_ref  
   (  
   col1 varchar2(30),  
   col2 DATE  
   )  
   partition BY range(col2)  
   (  
   partition tab_part_1 VALUES less than (to_date('2016-10-01','yyyy-mm-dd')),  
   partition tab_part_2 VALUES less than (to_date('2017-10-01','yyyy-mm-dd')),  
   partition tab_part_3 VALUES less than (to_date('2018-10-01','yyyy-mm-dd')),
   partition tab_part_4 VALUES less than (to_date('2019-10-01','yyyy-mm-dd')),
   partition tab_part_maxvalue values less than (maxvalue)
   );  

grant select,delete  on ref_owner.new_ref    to ref_conn;

数据初始化完成,接下来我们需要做的是在线重定义了。
其实脚本就是下面的几行内容。
exec dbms_redefinition.can_redef_table('REF_OWNER','test_online_ref',1);  
exec  DBMS_REDEFINITION.CAN_REDEF_TABLE('REF_OWNER','test_online_ref',2);  
exec  DBMS_REDEFINITION.START_REDEF_TABLE('REF_OWNER','test_online_ref','new_ref',NULL,2);  
exec  DBMS_REDEFINITION.FINISH_REDEF_TABLE('REF_OWNER','test_online_ref','new_ref');

在线重定义的过程中,我们会并发调用开始所说的3个脚本来调用。然后观察是否会存在ORA的错误。
第一个场景的脚本如下:
function test_conn
{
sqlplus -s ref_conn/oracle <<EOF
set feedback off
set time on
col systimestamp format a35
select systimestamp,count(*)from test_online_ref;
EOF
}

for i in {1..1000000}
do
test_conn
done

剩下两个场景的脚本,套路都是类似的,通过频繁的DML或者查询来完成
比如查询
select systimestamp,count(*)from test_online_ref;
比如DML
delete from test_online_ref where rownum<2;
commit;

很快就测试完毕,查看日志没有任何的ORA错误。所以我们可以得到一个肯定的测试结果就是在线重定义是可信赖的。
得到的日志类似下面的形式:
我们可以从日志看到数据在极短的时间内发生变化依旧可以保持数据的可持续访问变更。尽管会出现一定的卡顿,从日志里看大概是3秒钟,但是业务访问不会中断。
SYSTIMESTAMP                          COUNT(*)
----------------------------------- ----------
18-SEP-16 10.49.53.769959 PM +08:00    2923035

SYSTIMESTAMP                          COUNT(*)
----------------------------------- ----------
18-SEP-16 10.49.53.898239 PM +08:00    2922896

SYSTIMESTAMP                          COUNT(*)
----------------------------------- ----------
18-SEP-16 10.49.56.325261 PM +08:00    2922722

SYSTIMESTAMP                          COUNT(*)
----------------------------------- ----------
18-SEP-16 10.49.56.454042 PM +08:00    2922599

变更完成后,原来的分区表new_ref就变成了普通表。
SQL> select dbms_metadata.get_ddl('TABLE','NEW_REF','REF_OWNER') from dual;     
  CREATE TABLE "REF_OWNER"."NEW_REF"
   (    "COL1" VARCHAR2(30),
        "COL2" DATE,
         PRIMARY KEY ("COL1")
。。。。
大家有问题可以补充,有些场景下还是值得提倡的。

时间: 2024-09-20 19:41:27

在线重定义的补充测试的相关文章

[20170214]在线重定义测试.txt

[20170214]在线重定义测试.txt --//以前测试过,重复测试,因为生产系统要做一次相同的操作. --//实际的原理利用物化事务.注例子好像来源于piner的<构建oracle高可用环境>,当时版本是9i,好像没有 --//dbms_redefinition.copy_table_dependents函数. 1.准备工作: SCOTT@book> @ &r/ver1 PORT_STRING                    VERSION        BANNER

使用在线重定义重构亿级分区表

在我的印象中,一直以来都会收到一封报警邮件,之前分析过,排查过,最后发现是一个遗留问题,协调开发同学,停业务维护还是有一些难度,最后不了了之了,在今天又突然想起了这件事情,觉得还是需要做点什么. 报警邮件类似下面的形式: ZABBIX-监控系统: ------------------------------------ 报警内容: Disk I/O is overloaded on 10.127.2.134_xx机房_xxxx ----------------------------------

oracle在线重定义拷贝表结构的NOT NULL约束问题

以前测试和使用的时候还真的没发现这个问题,一直认为COPY_TABLE_DEPENDENTS会自动过滤NOT NULL约束. 然而事实并发如此,如果打算使用COPY_TABLE_DEPENDENTS过程复制索引.约束以及权限等相关对象,那么在建立目标表的时候,即使是NOT NULL约束都应该避免,否则NOT NULL约束的存在会引发错误: SQL> CREATE TABLE T AS 2  SELECT ROWNUM ID, OBJECT_NAME NAME, OBJECT_TYPE TYPE

【Oracle】在线重定义表

Oracle从9i版本开始提供了在线重定义表功能,通过调用DBMS_REDEFINITION包,可以在修改表结构的同时允许DML操作. 在线重定义表具有以下功能: 1 修改表的存储参数 2 可以将表转移到其他表空间 3 增加并行查询选项 4 增加或删除分区 5 重建表以减少碎片 6 将堆表改为索引组织表或相反的操作 7 增加或删除一个列 调用DBMS_REDEFINITION包需要EXECUTE_CATALOG_ROLE角色和以下权限: CREATE ANY TABLE ALTER ANY TA

【Oracle】利用在线重定义的方式改变普通表为分区表

将普通表改为分区表有如下几种方式: 1 创建一个和原表一样的分区表A_NEW ;    将insert A_NEW SELECT * FROM A;    将表A 命名为A_OLD 将A_NEW 该名为A; 2 利用在先重定义的方式!也是接下来要介绍的方法! 第一种方式需要停止应用对A的写访问;使用在线重定义的方式可以对应用透明! 测试例子如下:1 创建测试表 创建普通表: @bigtab.sql --tom 的大表创建脚本! 创建中间分区PART_TAB,使用PART_TAB来替换bigtab

基于 dbms_redefinition 在线重定义表

      Oracle 支持在线重定义表,也就是说我们可以在修改表结构(DDL)的同时进行相关的DQL.DML操作,使得前端的DML根本感觉不到表结构实际上已经发生了变化,对于用户而言是完全透明的.当然在线重定义期间,前端性能会稍微有所下降.Oracle提供的重定义包dbms_redefinition即是用与完成此操作.其实质是Oracle使用了智能物化视图及物化视图日志的方式.在对象结构重组期间,表现为一个本地对象的复制,重组期间发生的任何变化都会被刷新到最新.   1.在线重定义表的主要功

Oracle Online Redefinition在线重定义(上)

面对越来越多的7*24系统,运维人员进行工作可用的时间窗口变的越来越小.就在有限的时间窗口中,硬件检修.网络改造配置占据了很多时间.对数据库对象进行日常维护,越来越成为我们需要关注的问题.   进行数据重排.表分区.字段类型修改.字段增改这样的操作,在开发和测试环境上是比较容易进行的.即使数据表很大,操作耗时可能会很高,我们也能够通过一些非技术的手段赢取操作时间窗.但是对于投产系统而言,操作过程中的长时间锁定可能是业务不能接受的.这个时候,就可以考虑Oracle的一些Online操作技术.  

物化视图prebuilt和在线重定义

数据迁移中有一种解决方案很有亮点,如果表的数据量大,迁移涉及的表不多,同时对于维护时间有要求的情况下,物化视图的prebuilt方式就是一种很不错的选择. 大体的步骤和方法如下: 假设源环境是test_source,目标环境是test_target 在源环境中test_source的操作如下: Create table test_mv as select *from all_objects  ; alter table test_mv modify(object_id primary key);

关于分区表的在线重定义

目前项目中有一个问题,存在一个分区表,因为分区规则的问题,使得分区表中的数据分布很不均匀,数据都分区在了默认的maxvalue分区上.现在需要重新划分分区.从常规的角度来看,这中重新分区的问题一般有以下几个步骤. 1.数据备份,采用exp/expdp或者ctas的方式 2.truncate 分区表的数据 3.删除多余的分区,只保留maxvalue的分区 4.使用split partition进行分区 5.使用开始的数据备份,把数据导入. 对于这个问题,如果采用这种方式,势必会需要一定的downt