注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Oracle、MySQL资料及经验

.

 
 
 

日志

 
 

一个表数据同步的问题  

2014-08-16 20:56:23|  分类: sql与pl/sql |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

问题:有个表t,增删改操作时通过触发器记录日志到表log_t,开发人员每隔1分钟从log_t中同步一次数据,同步语句是: select * from log_t where id>上次同步的最大id and id<= (select max(id) from log_t); log_t表的id列由序列生成,使用时发现在表t繁忙时同步过来的数据不完整,如id=11和id=16的行同步过来了,id=12、13、14、15的行没有同步过来,但在log_t中能查到id=12、13、14、15的行。
还问:如果用id同步数据有问题的话,可否用scn、timestamp来同步数据?

我们来模拟一下这个问题:

--建测试表t
create table t as select * from emp;

--建表t的日志表
create table LOG_T
(
  next_value    NUMBER,
  current_value NUMBER,
  scn           NUMBER,
  create_time   DATE
);

--建log_t的序列
create sequence seq_test;

--建表t的触发器
create or replace trigger tri_t
    before insert or update or delete on t
    for each row
declare
    v_scn number;
begin
    select current_scn into v_scn from v$database;
    insert into log_t
    values
        (seq_test.nextval, seq_test.currval, v_scn, sysdate);
end;

会话1执行一条insert操作但未提交,此时log_t中没有记录:

一个表数据同步的问题 - 熊猫兔 - Oracle资料及经验
一个表数据同步的问题 - 熊猫兔 - Oracle资料及经验
 
 会话2执行insert操作并提交,此时log_t中有了记录
一个表数据同步的问题 - 熊猫兔 - Oracle资料及经验
 一个表数据同步的问题 - 熊猫兔 - Oracle资料及经验
会话1没提交所以在log_t中没有值,这也就导致了有部分数据没有同步过去。 
 
此时会话1执行commit,log_t中才有了会话1的记录:
一个表数据同步的问题 - 熊猫兔 - Oracle资料及经验 
这个就解释了去检查该表数据时发现没同步的值在表中是有的。
可以看到会话1记录的scn、create_time不是会话1插入log_t时的值,而是触发器被触发时的值,所以用scn和时间戳来同步数据也是不行的。
 
既然知道问题的原因了,就知道怎么避免这个问题了:
1. 会话尽快提交。
2. 估计会话多少秒后就会提交,如30秒,对原同步sql添加一个时间限制条件,只同步30秒之前的数据:
select * from log_t where id>上次同步的最大id and id<= (select max(id) from log_t) and create_time<sysdate-30/24/60/60;
 
 另外又考虑了以下方式:
往log_t插入时怎么把此时的scn插到表中,以便可通过scn值来同步,想到了11g的虚拟列,但没实现,如下:
--建立一个获取scn的函数
create or replace function f_getscn return number is
    v_scn number;
begin
    select current_scn into v_scn from v$database;
    return(v_scn);
end f_getscn;
 
给log_t添加一个虚拟列:
create table LOG_T
(
  next_value    NUMBER,
  current_value NUMBER,
  scn           NUMBER,
  current_scn   number as (f_getscn()) virtual,
  create_time   DATE
)
报错:ORA-30553: 函数不能确定
  评论这张
 
阅读(159)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018