不能靠存储过程单点实现可靠断点续传,必须结合外部状态持久化与日志位点机制;oracle存储过程无内置断点快照能力,变量或临时表记进度在会话中断时即丢失,真正可用的状态须落盘至专用日志表并与其主业务操作同事务提交。
不能靠存储过程单点实现可靠断点续传,必须结合外部状态持久化与日志位点机制。 oracle 存储过程本身无内置断点快照能力,强行在 pl/sql 里用变量或临时表记进度,一旦会话中断、实例崩溃或作业被 kill,状态即丢失——这不是“断点续传”,是“断点失传”。
DBLINK 增量同步必须带明确的切片依据
全量拉取(如 INSERT INTO t SELECT * FROM s@my_link)在百万级以上就不可控。真正能落地的增量逻辑只依赖两类字段:
- 时间戳字段(如
LAST_MODIFIED):需确保源表该字段严格递增、非空、有索引;不能用SYSDATE - 1/24这类硬编码窗口,否则漏数据 - 自增主键(如
ID):要求连续无跳号,且目标端已存在最大值可查;若存在批量插入导致 ID 跳变,需配合ROWID或分段扫描
示例关键片段:
v_last_time := NULL;<br>SELECT MAX(LAST_MODIFIED) INTO v_last_time FROM SYNC_LOG WHERE JOB_NAME = 'ORDERS_SYNC';<br>FOR r IN (SELECT * FROM ORDERS@MY_LINK WHERE LAST_MODIFIED > v_last_time) LOOP<br> MERGE INTO ORDERS_LOCAL t USING (SELECT r.*) s ON (t.ORDER_ID = s.ORDER_ID)<br> WHEN MATCHED THEN UPDATE SET ...<br> WHEN NOT MATCHED THEN INSERT ...;<br>END LOOP;<br>INSERT INTO SYNC_LOG (...) VALUES ('ORDERS_SYNC', SYSDATE, v_last_time);
存储过程里不能自己管“断点”,得靠外部元数据持久化
PL/SQL 变量、包级变量、甚至全局临时表都不具备跨会话持久性。真正可用的状态必须落盘:
- 专用日志表(如
SYNC_LOG):字段至少含JOB_NAME、LAST_SCN、LAST_TIME、LAST_ID、STATUS、UPDATE_TIME - 写入必须和主业务操作在同一事务中提交(
INSERT INTO SYNC_LOG ...; COMMIT;),否则出现“数据到了,但断点没记”的错位 - 避免用
DBMS_SCHEDULER的job_action直接调用匿名块——它不保证事务上下文延续;应封装为带事务控制的命名存储过程
ORA-01017 报错直接暴露 DBLINK 配置缺陷
哪怕账号密码完全正确,CREATE DATABASE LINK 没加双引号就会在 Oracle 12c+ 上失败。这是大小写敏感策略触发的默认行为,不是连不通。
- 错误写法:
create database link MY_LINK connect to scott identified by Tiger123 using 'ORCL_REMOTE'; - 正确写法:
create public database link MY_LINK connect to "scott" identified by "Tiger123" using 'ORCL_REMOTE'; - 测试别只查
DUAL@MY_LINK,要查真实小表:SELECT COUNT(1) FROM USER_TABLES@MY_LINK,否则权限不足问题会被掩盖
断点续传真正的复杂点不在“怎么记”,而在“记什么才不丢不重”。SCN 是 Oracle 最可靠的事务锚点,但存储过程无法安全获取并绑定 SCN 快照;所以生产环境的大规模迁移,最终都得退到 KFS、Goldengate 或 Data Pump + CONTINUE_CLIENT 这类有原生日志位点管理的工具链上——PL/SQL 只适合做轻量、可控、低频的补丁同步。











