物化视图刷新结合ADG的尝试(二)(r8笔记第57天)
之前写过一篇 物化视图刷新结合ADG的尝试,想必绝大多数的朋友看完再没有深究,其实也有些朋友做了建议,让我尝试prebuilt来做。这种数据迁移方式用的比较少,但是个人感觉还是很不错的。如果迁移的表不是很多,这种迁移方式还是非常强大的。 如果一个表非常大,我目前的设想就是通过ADG备库来把数据首先同步到统计库中,然后在主库端通过物化视图日志来增量刷新。
使用物化视图 prebuilt的方式确实可以实现,我产生了几个疑问,物化视图日志该什么时候创建。创建的时间太早或者太晚,对于增量刷新是否有影响,如果没有影响,我都幻想着可能是替代ogg的一个神器了。我做了下面三个测试。
同步测试,物化视图刷新基于rowid
统计库创建两个db link,一个指向主库,一个指向ADG
主库新增一个表 create table ACCtest20.test_mv_pri as select * from dba_objects where rownum<1001;
SQL> select count(*)from ACCtest20.test_mv_pri;
COUNT(*)
----------
1000
ADG+统计库创建表基于ADG的db link
create table test.test_mv_pri as select *from ACCtest20.test_mv_pri@public_test0;
主库增加一条数据
insert into ACCtest20.test_mv_pri(owner,object_id,object_name,object_type) values('test',1000001,'test','TABLE');
commit;
主库修改一条数据
SQL> select object_id from ACCtest20.test_mv_pri where rownum<2;
OBJECT_ID
----------
20
update ACCtest20.test_mv_pri set object_id=1000002 where object_id=20;
commit;
主库创建物化视图日志
create materialized view log on ACCtest20.test_mv_pri with rowid;
主库查询
SQL> select count(*)from ACCtest20.MLOG$_TEST_MV_PRI;
COUNT(*)
----------
0
主库+统计库创建物化视图基于主库的db link
create materialized view test.test_mv_pri on prebuilt table refresh fast with rowid as select *from ACCtest20.test_mv_pri@public_test0;
create materialized view test.test_mv_pri on prebuilt table refresh fast with rowid as select *from ACCtest20.test_mv_pri@public_test0
*
ERROR at line 1:
ORA-12058: materialized view cannot use prebuilt table
做到这一步发现已经完全不支持了,所以就放弃了rowid的方式。
继续做第二个测试。
同步测试 基于主键刷新 物化视图日志在全量同步后创建
统计库创建两个db link,一个指向主库,一个指向ADG
主库新增一个表
create table ACCtest20.test_mv_pri as select owner,object_id,object_name,object_type from all_objects where rownum<1001 and object_id is not null;
alter table ACCtest20.test_mv_pri modify(object_id primary key);
SQL> select count(*)from ACCtest20.test_mv_pri;
COUNT(*)
----------
1000
ADG+统计库创建表基于ADG的db link
create table test.test_mv_pri as select *from ACCtest20.test_mv_pri@public_test0;
主库增加一条数据
insert into ACCtest20.test_mv_pri(owner,object_id,object_name,object_type) values('test',1000001,'test','TABLE');
commit;
主库修改一条数据
SQL> select object_id from ACCtest20.test_mv_pri where rownum<2;
OBJECT_ID
----------
2
update ACCtest20.test_mv_pri set object_id=1000002 where object_id=2;
commit;
主库创建物化视图日志
create materialized view log on ACCtest20.test_mv_pri ;
主库查询
SQL> select count(*)from ACCtest20.MLOG$_TEST_MV_PRI;
COUNT(*)
----------
0
SQL> select count(*)from ACCtest20.test_mv_pri ;
COUNT(*)
----------
1001
主库+统计库创建物化视图基于主库的db link
create materialized view test.test_mv_pri on prebuilt table refresh fast as select *from ACCtest20.test_mv_pri@public_test0;
查看数据条数
SQL> select count(*)from test.test_mv_pri;
COUNT(*)
----------
1000
增量刷新数据,查看数据条数是否完全同步
exec dbms_mview.refresh('test.test_mv_pri','F');
SQL> select count(*)from test.test_mv_pri;
COUNT(*)
----------
1000
所以得到的结论是,在物化视图快速刷新的场景中,在本次测试中,在全量同步数据之后创建物化视图日志,快速刷新可能数据不一致,在全量同步的过程中,任何的dml操作可能都会丢失。
同步测试 基于主键刷新 物化视图日志在全量同步前创建
统计库创建两个db link,一个指向主库,一个指向ADG
主库新增一个表
create table ACCtest20.test_mv_pri as select owner,object_id,object_name,object_type from all_objects where rownum<1001 and object_id is not null;
alter table ACCtest20.test_mv_pri modify(object_id primary key);
SQL> select count(*)from ACCtest20.test_mv_pri;
COUNT(*)
----------
1000
主库创建物化视图日志
create materialized view log on ACCtest20.test_mv_pri ;
ADG+统计库创建表基于ADG的db link
create table test.test_mv_pri as select *from ACCtest20.test_mv_pri@public_test0;
主库增加一条数据
insert into ACCtest20.test_mv_pri(owner,object_id,object_name,object_type) values('test',1000001,'test','TABLE');
commit;
主库修改一条数据
SQL> select object_id from ACCtest20.test_mv_pri where rownum<2;
OBJECT_ID
----------
2
update ACCtest20.test_mv_pri set object_id=1000002 where object_id=2;
commit;
主库查询
SQL> select count(*)from ACCtest20.MLOG$_TEST_MV_PRI;
COUNT(*)
----------
3
SQL> select count(*)from ACCtest20.test_mv_pri ;
COUNT(*)
----------
1001
主库+统计库创建物化视图基于主库的db link
create materialized view test.test_mv_pri on prebuilt table refresh fast as select *from ACCtest20.test_mv_pri@public_test0;
查看数据条数
SQL> select count(*)from test.test_mv_pri;
COUNT(*)
----------
1000
增量刷新数据,查看数据条数是否完全同步
exec dbms_mview.refresh('test.test_mv_pri','F');
SQL> select count(*)from test.test_mv_pri;
COUNT(*)
----------
1000
主库查询
select count(*)from ACCtest20.MLOG$_TEST_MV_PRI;
COUNT(*)
----------
0
数据不一致
主库继续插入一条数据
insert into ACCtest20.test_mv_pri(owner,object_id,object_name,object_type) values('test',1000003,'test','TABLE');
commit;
增量刷新数据,查看数据条数是否完全同步
SQL> select count(*)from ACCtest20.test_mv_pri ;
COUNT(*)
----------
1002
结论,在这种场景中,可能会有数据丢失的情况。主要原因就是统计库的物化视图创建时间晚于源库的物化视图日志时间。
我这种测试不是说物化视图prebuilt的方式不好,而是在这种场景中还是会有一些影响。如果通过主库全量同步数据,再增量刷新肯定是没有问题的。我这个场景只是想通过ADG来实现间接的全量刷新,不是主流的使用方法。
- SQL学习之使用常用函数处理数据
- Javascript快速入门(上篇)
- SQL练习之不反复执行相同的计算
- SQL练习之求解填字游戏
- 快速入门系列--WCF--08扩展与新特性
- SQL练习之两个列值的交换
- Parcel,零配置开发 React 应用!
- 像 React Native 开发 APP 一样,用wn-cli 开发 weapp (微信小程序)
- 正则表达式快速入门
- JavaScript之<script>标签简介
- 数控机床数控系统选择4大关键要素
- Python快速入门
- Jquer学习之jQuery(function(){})与(function(){})(jQuery)之间的区别
- 服务端常见性能隐患分享
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法