oracle flashback data archive闪回数据归档天坑之XID重用导致闪回查询数据重复
我们有个系统使用了Oracle flashback data archive闪回数据归档特性来作为基于时间点的恢复机制,在频繁插入、更新期间发现SYS_FBA_HIST_NNNN表中的XID被两个事务重用了,导致start_scn相同,于是在执行as of scn/timestamp查询的时候,相同rowid的记录会出来两条,无论是oracle 11.2.0.4还是oracle 18c都能重现,前者几乎100%,后者概率低很多(一开始LZ本地用18c跑了连续四五次都没有出现,以为解决了,后来测试又验证出来了)。因为公司metalink账号都被停了,所以只能求助了,麻烦各位有mos账号的同学或者有遇到的同学帮忙查下是否是bug,或者对应的补丁。完整重现现象示例如下:
create flashback archive default fda_test_1day tablespace "USERS" retention 1 day;
create table xyz_test (
c_tenantid varchar2(20) DEFAULT ' ' NOT NULL,
c_tacode varchar2(2) DEFAULT ' ' ,
c_fundacco varchar2(12) DEFAULT ' ' ,
c_agencyno varchar2(9) DEFAULT ' ' ,
c_netno varchar2(9) DEFAULT ' ' ,
c_tradeacco varchar2(24) DEFAULT ' ' ,
c_fundcode varchar2(12) DEFAULT ' ' ,
c_sharetype char(1) DEFAULT ' ' ,
d_cdate number(8,0) DEFAULT 0 ,
c_cserialno varchar2(20) DEFAULT ' ' NOT NULL,
c_sourcetype char(1) DEFAULT ' ' ,
f_remainshares number(16,2) DEFAULT 0.0 ,
d_registdate number(8,0) DEFAULT 0 ,
f_oricfmbalance number(16,2) DEFAULT 0.0 ,
f_oricfmshares number(16,2) DEFAULT 0.0 ,
f_orinetvalue number(7,4) DEFAULT 0.0 ,
c_orisource char(1) DEFAULT ' ' ,
f_ruleagio number(5,4) DEFAULT 1.0 ,
f_oriagio number(5,4) DEFAULT 1.0 ,
f_maxallotratio number(5,4) DEFAULT 0.0 ,
f_minredeemratio number(5,4) DEFAULT 0.0 ,
c_holdflag char(1) DEFAULT ' ' ,
c_acceptmode char(1) DEFAULT ' ' ,
c_firstcserailno varchar2(20) DEFAULT ' ' ,
c_fundmethod varchar2(2) DEFAULT ' ' ,
c_bankno varchar2(60) DEFAULT ' ' ,
c_subfundmethod varchar2(2) DEFAULT ' ' ,
f_managefare number(16,2) DEFAULT 0.0 ,
f_interestshare number(16,2) DEFAULT 0.0 ,
d_lastdeductdate number(8,0) DEFAULT 0 ,
f_income number(16,2) DEFAULT 0.0 ,
f_newincome number(16,2) DEFAULT 0.0 ,
c_specialcode varchar2(20) DEFAULT ' ' ,
f_pendsubmit02shr number(16,2) DEFAULT 0.0 ,
f_pendsubmit03shr number(16,2) DEFAULT 0.0 ,
f_pendsubmit50shr number(16,2) DEFAULT 0.0 ,
f_assignshare number(16,2) DEFAULT 0.0 ,
f_pendsubmit13shr number(16,2) DEFAULT 0.0 ,
f_pendsubmit16shr number(16,2) DEFAULT 0.0 ,
f_lastremainshares number(16,2) DEFAULT 0.0 ,
f_pendsubmit14shr number(16,2) DEFAULT 0.0 ,
f_pendsubmit15shr number(16,2) DEFAULT 0.0 ,
f_lastincome number(16,2) DEFAULT 0.0 ,
d_orilastdeductdate number(8,0) DEFAULT 0 ,
f_costprice number(15,12) DEFAULT 0.0 ,
f_lastmanagefare number(16,2) DEFAULT 0.0 ,
f_apportionratio number(9,8) DEFAULT 0.0 ,
f_fareratio number(5,4) DEFAULT 0.0 ,
f_backfareratio number(9,8) DEFAULT 0.0 ,
f_minbackratio number(5,4) DEFAULT 0.0 ,
f_orifareratio number(5,4) DEFAULT 0.0 ,
d_cyclestartdate number(8,0) DEFAULT 0 ,
d_cycleenddate number(8,0) DEFAULT 0 ,
d_cyclenextdate number(8,0) DEFAULT 0 ,
l_cycle number(10,0) DEFAULT 0 ,
f_evennetvalue number(7,4) DEFAULT 0.0 ,
c_protectflag char(1) DEFAULT ' ' ,
f_backfare number(16,2) DEFAULT 0.0 ,
f_costfare number(16,2) DEFAULT 0.0 ,
c_lastoutfundcode varchar2(20) DEFAULT ' ' ,
f_redeemedbaseshr number(16,2) DEFAULT 0.0 ,
l_incserno number(20,0) DEFAULT 0 ,
f_lastdeductnetvalue number(7,4) DEFAULT 0.0 ,
f_lastdeductasset number(16,2) DEFAULT 0.0 ,
f_newnetvalue number(7,4) DEFAULT 0.0 ,
f_newasset number(16,2) DEFAULT 0.0 ,
c_actcode varchar2(20) DEFAULT ' '
) enable row movement,rowdependencies,flashback archive;
alter table xyz_test add primary key(c_cserialno, c_tenantid);
-- 创建测试存储过程
create or replace procedure insert_sharedetail is
i number;
fundcode VARCHAR2(10);
begin
i:=0;
loop
i:=i+1;
if i>2000 then
exit;
end if;
fundcode := replace(lpad(floor(i/100000),6),' ','0');
INSERT INTO xyz_test(C_TENANTID, C_TACODE, C_FUNDACCO, C_AGENCYNO, C_NETNO, C_TRADEACCO, C_FUNDCODE, C_SHARETYPE, D_CDATE, C_CSERIALNO, C_SOURCETYPE, F_REMAINSHARES, D_REGISTDATE, F_ORICFMBALANCE, F_ORICFMSHARES, F_ORINETVALUE, C_ORISOURCE, F_RULEAGIO, F_ORIAGIO, F_MAXALLOTRATIO, F_MINREDEEMRATIO, C_HOLDFLAG, C_ACCEPTMODE, C_FIRSTCSERAILNO, C_FUNDMETHOD, C_BANKNO, C_SUBFUNDMETHOD, F_MANAGEFARE, F_INTERESTSHARE, D_LASTDEDUCTDATE, F_INCOME, F_NEWINCOME, C_SPECIALCODE, F_PENDSUBMIT02SHR, F_PENDSUBMIT03SHR, F_PENDSUBMIT50SHR, F_ASSIGNSHARE, F_PENDSUBMIT13SHR, F_PENDSUBMIT16SHR, F_LASTREMAINSHARES, F_PENDSUBMIT14SHR, F_PENDSUBMIT15SHR, F_LASTINCOME, D_ORILASTDEDUCTDATE, F_COSTPRICE, F_LASTMANAGEFARE, F_APPORTIONRATIO, F_FARERATIO, F_BACKFARERATIO, F_MINBACKRATIO, F_ORIFARERATIO, D_CYCLESTARTDATE, D_CYCLEENDDATE, D_CYCLENEXTDATE, L_CYCLE, F_EVENNETVALUE, C_PROTECTFLAG, F_BACKFARE, F_COSTFARE, C_LASTOUTFUNDCODE, F_REDEEMEDBASESHR, L_INCSERNO, F_LASTDEDUCTNETVALUE, F_LASTDEDUCTASSET, F_NEWNETVALUE, F_NEWASSET, C_ACTCODE) VALUES ('*', 'F6', 'F60000000031', '002', '002', '110002003', fundcode, 'A', '20180914', replace(lpad(i,20),' ','0'), '0', '10000.50', '20180914', '10000.50', '10000.50', '1', '0', '1', '1', '0', '0', '0', ' ', '6449654002077306883', ' ', NULL, ' ', NULL, '0', NULL, NULL, NULL, ' ', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '1', NULL, '0', '0', '0', '0', NULL, NULL, NULL, NULL, NULL, '0', '0', NULL, '0', NULL, NULL, '6449654002081501184', '0', '0', '0', '0', ' ');
end loop;
commit;
end insert_sharedetail;
/
create or replace procedure update_sharedetail is
i number;
fundcode VARCHAR2(10);
begin
update xyz_test set c_fundcode = '027010';
commit;
end update_sharedetail;
/
create or replace procedure delete_sharedetail is
i number;
fundcode VARCHAR2(10);
begin
delete from xyz_test;
commit;
end delete_sharedetail;
/
create or replace procedure sharedetail is
i number;
fundcode VARCHAR2(10);
begin
i:=0;
loop
i:=i+1;
if i>200 then
exit;
end if;
insert_sharedetail();
update_sharedetail();
delete_sharedetail();
end loop;
end sharedetail;
/
-- 调用测试,在纯SSD笔记本下,执行大约500秒,在HDD下可能会半个小时左右。
call sharedetail();
-- 查询被重用且start_scn不正确的xid,如果记录为空,代表没有被覆盖,如果不为空,代表有被覆盖。
-- 有可能一次运行不出现,多跑两次一定会出来。此时as of timestamp会有两条相同记录,闪回不应该如此。
select * from dba_flashback_archive_tables where table_name='XYZ_TEST'; -- 查询对应的闪回归档历史表
select to_char(scn_to_timestamp(startscn),'yyyy-MM-dd HH24:mi:SS:FF'),
to_char(scn_to_timestamp(endscn),'yyyy-MM-dd HH24:mi:SS:FF'),
to_char(scn_to_timestamp(nextstart),'yyyy-MM-dd HH24:mi:SS:FF'),
to_char(scn_to_timestamp(nextend),'yyyy-MM-dd HH24:mi:SS:FF'),
startscn,
endscn,
nextstart,
nextend,
errxid,
a.*
from (
select lead(startscn, 1, dbms_flashback.get_system_change_number) over (partition by c_cserialno order by endscn, startscn) nextstart,
lead(endscn, 1, dbms_flashback.get_system_change_number) over (partition by c_cserialno order by endscn, startscn) nextend,
lead(xid, 1, null) over(partition by c_cserialno order by endscn, startscn) errxid,
a.*
from SYS_FBA_HIST_116447 a) a -- SYS_FBA_HIST_116447为上面查询出来对应的闪回归档历史表
where endscn < startscn or nextstart < endscn or nextend < nextstart
order by a.c_cserialno, a.endscn, a.startscn;
问题已解决,关闭。
oracle flashback data archive闪回数据归档天坑之XID重用导致闪回查询数据重复的更多相关文章
- oracle闪回、闪回数据归档Flashback Data Archive (Oracle Total Recall)的真正强大之处、11gR2增强以及合理使用
oracle的闪回很早就出来了,准确的说一直以来应该都较少被真正用户广为使用,除了dba和极少部分开发人员偶尔用于逻辑出错.误删恢复之外,较少被用于产生更有价值的用途. 各种闪回表flashback ...
- flashback data archive (转)
闪回数据归档(Flashback Data Archive) 在Oracle 11g当中,对闪回技术再次进行了扩展,提供了一个全新的flashback方式,称之为闪回数据归档,本节我们将对闪回数据归档 ...
- 闪回之 Flashback Data Archive
背景:Oracle 11g 中 Flashback Data Archive 特性.将变化数据另外存储到创建的闪回归档区(Flashback Archive)中,以和 undo 区别开来,这样就可以为 ...
- Flashback Data Archive ( Oracle Total Recall ) introduced in 11g
Flashback Data Archive feature is part of Oracle Total Recall technology. Flashback Data Archive fea ...
- [每日一题] 11gOCP 1z0-053 :2013-09-29 Flashback Data Archive ...................................6
转载请注明出处:http://blog.csdn.net/guoyjoe/article/details/12205299 正确答案:A 具体请参考:http://blog.csdn.net/guoy ...
- 11G新特性 -- flashback data archive(1)
虽然可以依赖undo数据来查询row的旧版本数据,甚至可以执行逻辑恢复.但是你不能期待在undo中找到非常旧的数据.undo数据主要是用来提供读一致性. 在11G中,提供了Flashback Data ...
- 11G新特性 -- flashback data archive(2)
创建Flashback Data Archive用户需要授予dba或flashback archive administer系统特权.flashback archive administer系统特权包 ...
- hbase数据加盐(Salting)存储与协处理器查询数据的方法
转自: https://blog.csdn.net/finad01/article/details/45952781 ----------------------------------------- ...
- Oracle 闪回归档(Flashback Data Archive)
--检查权限 SELECT * FROM dba_sys_privs WHERE privilege LIKE '%FLASH%'; --设置权限 GRANT dba TO testuser;--设置 ...
随机推荐
- LeetCode - 804. Unique Morse Code Words
International Morse Code defines a standard encoding where each letter is mapped to a series of dots ...
- Excel反序排列
实际工作中有这样一个需求,将Excel列表中所有的条目进行反序排列,有人说这还不简单直接选中某一列按照这列排序(升序或降序)就可以了. 但问题是这里没有可以参考的列,进行排序. 比如: 想转换为: 那 ...
- vue 中的数据绑定
vue当中有个v-model, 是怎么实现的呢?其实是利用了$event. <div id="app"> <!-- 输入什么,就输出什么 --> <i ...
- 浅谈SFTP和FTP的区别
一.适用场景 我们平时习惯了使用ftp来上传下载文件,尤其是很多Linux环境下,我们一般都会通过第三方的SSH工具连接到Linux,但是当我们需要传输文件到Linux服务器当中,很多人习惯用ftp来 ...
- swust oj 1068
图的按录入顺序深度优先搜索 5000(ms) 10000(kb) Tags: 深度优先 图的深度优先搜索类似于树的先根遍历,即从某个结点开始,先访问该结点, 然后深 ...
- HTML01
1.什么是HTML?(Hyper Text Markup Language:超文本标记语言) 超文本:功能比普通文本更加强大 标记语言:使用一组标签对内容进行描述的一门语言(它不是编程语言) 2.为什 ...
- Java Web请求和响应机制
1.请求响应流程图 =================== 服务器处理请求的流程: 服务器每次收到请求时,都会为这个请求开辟一个新的线程. 服务器会把客户端的请求数据封装到request对象中,req ...
- 什么是Rollback Segment(已truncate和delete 命令为例)?
Rollback Segments是在你数据库中的一些存储空间,它用来临时的保存当数据库数据发生改变时的先前值,Rollback Segment主要有两个目的: 1. 如果因为某种原因或者其他用用户想 ...
- 在不同语言中static的用法
static (计算机高级语言) 编辑 像在VB,C#,C,C++,Java,PHP中我们可以看到static作为关键字和函数出现,在其他的高级计算机语言如FORTRAN.ALGOL.COBOL.BA ...
- JAVA微信支付代码(WeChatPay.java 才是调用类)
微信官方文档:https://pay.weixin.qq.com/wiki/doc/api/index.html MD5Util.java package weixin; import java.se ...