问题描述
嗨,
我有一个关于数据仓库的问题,我正在寻找指导,如何使用数据库的功能最好地实现这个目标。
假设我们有一个非常大的表在一个实例中,并正在寻找从它每晚检索所有新记录。
我经常看到这样做的过程:
因此,该流程定期(可能是每天晚上)运行并检索自上次运行以来更新/创建的所有记录。此时, last_extra_date将设置为当前日期,以便下次运行。
我对此的问题是,如果我们有在运行“提取”查询之前启动的事务,然后提交,则可能导致数据丢失。
例如,假定以下虚拟时间戳:
14点20分。开始事务A
14:20:01。开始提取例程
14:20:05。完成提取程序并将最后提取日期设置为14:20:01
14点20分10分。提交事务A
所以接下来的晚上,我提取了14:20:01以后的记录,导致我丢失了交易A。
我看到的许多实现(包括Oracle自己的BI应用程序例程)使用了“修剪天数”的概念,在这一概念中,它们将以X天的天数来抵消日期,因此您总是检索的数据量比实际需要的要多出至少X天。那么,镶块是:
不过,我觉得这有点...怪诞的就像每晚都有大量的开销处理工作,这些工作在现实中很可能会发生一次。
所以...除了在更新等过程中锁定整个表之外,您是否推荐使用任何特定的方法或方法来实现此类功能?我以前听到有人提到MV Logs作为一种可能的解决方案,但我不确定它是否可行?
任何建议或指点都非常感谢。
谢谢,
约翰
我有一个关于数据仓库的问题,我正在寻找指导,如何使用数据库的功能最好地实现这个目标。
假设我们有一个非常大的表在一个实例中,并正在寻找从它每晚检索所有新记录。
Create Table xxdemo As
Select 'Record ' || To_Char(level, 'fm9999') myrecord, Sysdate -1 last_update_date
From dual
Connect By Level < 10000;
Insert Into xxdemo(myrecord, last_update_date)
Select 'Rec ' || To_Char(level, 'fm9999') myrecord, Sysdate last_update_date
From dual
Connect By Level < 10000;
Create Index xxdemo_n1 On xxdemo(last_update_date);我经常看到这样做的过程:
Select * From xxdemo Where last_update_date >= :last_extract_date
因此,该流程定期(可能是每天晚上)运行并检索自上次运行以来更新/创建的所有记录。此时, last_extra_date将设置为当前日期,以便下次运行。
我对此的问题是,如果我们有在运行“提取”查询之前启动的事务,然后提交,则可能导致数据丢失。
例如,假定以下虚拟时间戳:
14点20分。开始事务A
14:20:01。开始提取例程
14:20:05。完成提取程序并将最后提取日期设置为14:20:01
14点20分10分。提交事务A
所以接下来的晚上,我提取了14:20:01以后的记录,导致我丢失了交易A。
我看到的许多实现(包括Oracle自己的BI应用程序例程)使用了“修剪天数”的概念,在这一概念中,它们将以X天的天数来抵消日期,因此您总是检索的数据量比实际需要的要多出至少X天。那么,镶块是:
Insert Into xxdemo(...) Values (...) Where Not Exist (Select 'Already Exists' From xxdemo);
不过,我觉得这有点...怪诞的就像每晚都有大量的开销处理工作,这些工作在现实中很可能会发生一次。
所以...除了在更新等过程中锁定整个表之外,您是否推荐使用任何特定的方法或方法来实现此类功能?我以前听到有人提到MV Logs作为一种可能的解决方案,但我不确定它是否可行?
任何建议或指点都非常感谢。
谢谢,
约翰
专家解答
不要忘记在更新期间不需要锁定表,只是为了获得一致的记录集。
所以你可以编写类似这样的代码:
-在独占模式下锁定表T等待10 ;
-打开光标用于选择* from T where last_udpate >...;
-承诺;
-现在你去拿
所以这锁只是暂时的。
或者,如果“last_update”是过去很长的时间(例如,您得到的是“昨天”记录,因此打开交易的可能性非常低,您可以通过再次检查来查询v$事务,以确保没有打开的事务是那么老。
所以你可以编写类似这样的代码:
-在独占模式下锁定表T等待10 ;
-打开光标用于选择* from T where last_udpate >...;
-承诺;
-现在你去拿
所以这锁只是暂时的。
或者,如果“last_update”是过去很长的时间(例如,您得到的是“昨天”记录,因此打开交易的可能性非常低,您可以通过再次检查来查询v$事务,以确保没有打开的事务是那么老。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




