问题场景:
Oracle数据库使用dblink进行跨库关联查询,遇到ORA-01555错误
此行为的示例如下所示:
DBLINK Local DBLINK Remote--------------------------------- --------------------------SCN SCN10 SELECT * FROM R1@<DBLINK>,L1 ------> 30 (Before image at SCN:10 is available)WHERE R1.C1 = L1.C1 SCN:10 :30 Succeed (Sync with DBLINK Remote)30 3030 (No update operations) : Multiple updates30 10030 SELECT * FROM R1@<DBLINK>,L1 ------> 100 (No before image at SCN:30)WHERE R1.C1 = L1.C1 SCN:30 :30 ORA-1555 (Failed to sync DBLINK) 100* R1 is a table located on the DBLINK Remote side, and L1 is a table located on the DBLINK Remote side.
1. 从本地端执行连接本地表和远程表的 SELECT 语句。用于此查询的 SCN 是本地端的 SCN:10。远程端位于 SCN:30,但由于它仍然具有 SCN:10 的 before 映像,因此查询成功。(注:返回的数据反映了 SCN:10 的状态)
2. 在远程端执行多次更新,将 SCN 增加到 SCN:100。同时,本地不进行任何作,其 SCN 保持在 SCN:30。如果本地的 SCN 高于远程,则在同步期间将相应地提高远程的 SCN。
3. 在 DBLINK Local 上执行 SELECT 语句,连接来自本地和远程 DBLink 的表。此时,SELECT使用的SCN是本地端的SCN:30。在偏远方面,SCN 已经晋升到 100。如果无法通过远程端的 UNDO 生成 SCN:30 所需的 before 映像,则无法保持读取一致性,并且将发生 ORA-1555 错误。此外,如果发生 ORA-1555,则不会进行 SCN 同步。在这种情况下,DBLINK 本地端保持在 SCN:30,重复执行相同的 SQL 将继续导致 ORA-1555。
解决方法:
执行指定SQL之前先执行虚拟查询。
执行使用数据库链接的 SQL 将触发 SCN 同步。为避免 ORA-1555,可以在执行可能导致错误的 SQL 之前使用数据库链接运行虚拟 SELECT。使用 DUAL 表的 SELECT(如下例所示)就足够了:
这可确保在主 SQL 开始之前进行 SCN 同步。