问题场景:
Oracle数据库使用dblink进行跨库关联查询,遇到ORA-01555错误
此行为的示例如下所示:
DBLINK Local DBLINK Remote
--------------------------------- --------------------------
SCN SCN
10 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 30
30 (No update operations) : Multiple updates
30 100
30 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(如下例所示)就足够了:
SELECT * FROM DUAL@<DATABASE_LINK_NAME>;
这可确保在主 SQL 开始之前进行 SCN 同步。
浙公网安备 33010602011771号